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

[PATCH] 2.5.18 IDE 73

 - Merge ide-probe.c and ide-features.c in to one single file.  They are
   mutually doing basically the same and in esp. in case of the device ID
   retrieval there *is* quite a lot of code duplication between them.
   ide-geometry.c fits there as well.

 - Remove ide_xfer_verbose - it wasn't really used.

 - Don't allow check_partition to be more clever then the writer of a driver.
   It was interfering with drivers which check partitions as they go and
   finally if we want to spew something about it - we can do it ourself.

 - Eliminate ide_geninit(). We scan for partitions now inside the recently
   introduced attach method. register_disk() is broken by the way and 90% of
   places where it's used it is doing literally nothing. Either some one didn't
   finish some code or the code is basically just junk from the past.

   Anyway we grok the partitions now one by one as we detect the channels.

 - ide_driveid_update is gone. We don't report the drive id through /proc/ide
   and we don't have to update it any longer on the fly. Still someone out there
   complaining that it went away!?

 - Use the global driver spin-lock to protect data structure access in the
   ide_register_subdriver() function instead of blatantly disabling all
   interrupts.
parent 18c16b33
......@@ -212,7 +212,7 @@ When ide.c is used as a module, you can pass command line parameters to the
driver using the "options=" keyword to insmod, while replacing any ',' with
';'. For example:
insmod ide.o options="ide0=serialize ide2=0x1e8;0x3ee;11"
insmod ide.o options="ide0=serialize ide1=serialize ide2=0x1e8;0x3ee;11"
================================================================================
......@@ -220,50 +220,69 @@ driver using the "options=" keyword to insmod, while replacing any ',' with
Summary of ide driver parameters for kernel "command line":
----------------------------------------------------------
"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".
"hdx=noprobe" : drive may be present, but do not probe for it
"hdx=none" : drive is NOT present, ignore cmos and do not probe
"hdx=nowerr" : ignore the WRERR_STAT bit on this drive
"hdx=cdrom" : drive is present, and is a cdrom drive
"hdx=cyl,head,sect" : disk drive is present, with specified geometry
"hdx=autotune" : driver will attempt to tune interface speed
to the fastest PIO mode supported,
if possible for this drive only.
Not fully supported by all chipset types,
and quite likely to cause trouble with
older/odd IDE drives.
to the fastest PIO mode supported,
if possible for this drive only.
Not fully supported by all chipset types,
and quite likely to cause trouble with
older/odd IDE drives.
"hdx=slow" : insert a huge pause after each access to the data
port. Should be used only as a last resort.
port. Should be used only as a last resort.
"hdxlun=xx" : set the drive last logical unit
"idebus=xx" : inform IDE driver of VESA/PCI bus speed in MHz,
where "xx" is between 20 and 66 inclusive,
used when tuning chipset PIO modes.
For PCI bus, 25 is correct for a P75 system,
30 is correct for P90,P120,P180 systems,
and 33 is used for P100,P133,P166 systems.
If in doubt, use idebus=33 for PCI.
As for VLB, it is safest to not specify it.
Bigger values are safer than smaller ones.
where "xx" is between 20 and 66 inclusive,
used when tuning chipset PIO modes.
For PCI bus, 25 is correct for a P75 system,
30 is correct for P90,P120,P180 systems,
and 33 is used for P100,P133,P166 systems.
If in doubt, use idebus=33 for PCI.
As for VLB, it is safest to not specify it.
Bigger values are safer than smaller ones.
"idex=noprobe" : do not attempt to access/use this interface
"idex=base" : probe for an interface at the addr specified,
where "base" is usually 0x1f0 or 0x170
and "ctl" is assumed to be "base"+0x206
where "base" is usually 0x1f0 or 0x170
and "ctl" is assumed to be "base"+0x206
"idex=base,ctl" : specify both base and ctl
"idex=base,ctl,irq" : specify base, ctl, and irq number
"idex=autotune" : driver will attempt to tune interface speed
to the fastest PIO mode supported,
for all drives on this interface.
Not fully supported by all chipset types,
and quite likely to cause trouble with
older/odd IDE drives.
"idex=noautotune" : driver will NOT attempt to tune interface speed
This is the default for most chipsets,
except the cmd640.
"idex=serialize" : do not overlap operations on idex and ide(x^1)
to the fastest PIO mode supported,
for all drives on this interface.
Not fully supported by all chipset types,
and quite likely to cause trouble with
older/odd IDE drives.
"idex=noautotune" : driver will NOT attempt to tune interface speed
This is the default for most chipsets,
except the cmd640.
"idex=serialize" : do not overlap operations on idex. Please note
that you will have to specify this option for
both the respecitve primary and secondary channel
to take effect.
"idex=reset" : reset interface after probe
"idex=dma" : automatically configure/use DMA if possible.
The following are valid ONLY on ide0, which usually corresponds to the first
......@@ -304,6 +323,6 @@ drives.
mlord@pobox.com
--
Wed Apr 17 22:52:44 CEST 2002 edited by Marcin Dalecki
For current maintainers of this stuff, please see the linux/MAINTAINERS file.
Wed Apr 17 22:52:44 CEST 2002 edited by Marcin Dalecki, the current
maintainer.
......@@ -8,7 +8,7 @@
# In the future, some of these should be built conditionally.
#
export-objs := ide-taskfile.o main.o ide.o ide-features.o ide-probe.o quirks.o pcidma.o tcq.o \
export-objs := ide-taskfile.o main.o ide.o probe.o quirks.o pcidma.o tcq.o \
atapi.o ataraid.o
obj-$(CONFIG_BLK_DEV_HD) += hd.o
......@@ -68,7 +68,7 @@ obj-$(CONFIG_BLK_DEV_ATARAID) += ataraid.o
obj-$(CONFIG_BLK_DEV_ATARAID_PDC) += pdcraid.o
obj-$(CONFIG_BLK_DEV_ATARAID_HPT) += hptraid.o
ide-mod-objs := ide-taskfile.o main.o ide.o ide-probe.o ide-geometry.o ide-features.o \
ide-mod-objs := ide-taskfile.o main.o ide.o probe.o \
ioctl.o atapi.o ata-timing.o$(ide-obj-y)
include $(TOPDIR)/Rules.make
......@@ -82,4 +82,5 @@ extern void ata_timing_merge(struct ata_timing *a, struct ata_timing *b,
extern struct ata_timing* ata_timing_data(short speed);
extern int ata_timing_compute(struct ata_device *drive,
short speed, struct ata_timing *t, int T, int UT);
#endif
......@@ -76,8 +76,6 @@ static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count)
byte cs5530_proc = 0;
extern char *ide_xfer_verbose (byte xfer_rate);
/*
* Set a new transfer mode at the drive
*/
......@@ -85,7 +83,7 @@ int cs5530_set_xfer_mode(struct ata_device *drive, byte mode)
{
int error = 0;
printk("%s: cs5530_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode));
printk("%s: cs5530_set_xfer_mode(%02x)\n", drive->name, mode);
error = ide_config_drive_speed(drive, mode);
return error;
......
......@@ -94,8 +94,6 @@ static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count)
byte hpt34x_proc = 0;
extern char *ide_xfer_verbose(byte xfer_rate);
static void hpt34x_clear_chipset(struct ata_device *drive)
{
unsigned int reg1 = 0, tmp1 = 0;
......@@ -132,12 +130,12 @@ static int hpt34x_tune_chipset(struct ata_device *drive, byte speed)
pci_write_config_dword(drive->channel->pci_dev, 0x48, tmp2);
#if HPT343_DEBUG_DRIVE_INFO
printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \
printk("%s: %02x drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \
" (0x%02x 0x%02x) 0x%04x\n",
drive->name, ide_xfer_verbose(speed),
drive->name, speed,
drive->dn, reg1, tmp1, reg2, tmp2,
hi_speed, lo_speed, err);
#endif /* HPT343_DEBUG_DRIVE_INFO */
#endif
if (!drive->init_speed)
drive->init_speed = speed;
......
......@@ -27,8 +27,6 @@
#include <asm/io.h>
#include <asm/page.h>
extern char *ide_xfer_verbose (byte xfer_rate);
/*
* Maximum number of interfaces per card
*/
......@@ -372,8 +370,8 @@ icside_config_if(struct ata_device *drive, int xfer_mode)
else
drive->drive_data = 480;
printk("%s: %s selected (peak %dMB/s)\n", drive->name,
ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
printk("%s: %02x selected (peak %dMB/s)\n", drive->name,
xfer_mode, 2000 / drive->drive_data);
drive->current_speed = xfer_mode;
......
......@@ -871,9 +871,10 @@ int cdrom_read_check_ireason(struct ata_device *drive, struct request *rq, int l
/* Throw some data at the drive so it doesn't hang
and quit this request. */
while (len > 0) {
int dum = 0;
atapi_write(drive, &dum, sizeof (dum));
len -= sizeof (dum);
u8 dummy[4];
atapi_write(drive, dummy, sizeof(dummy));
len -= sizeof(dummy);
}
} else if (ireason == 1) {
/* Some drives (ASUS) seem to tell us that status
......@@ -1293,10 +1294,10 @@ static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *r
/* If we haven't moved enough data to satisfy the drive,
add some padding. */
while (len > thislen) {
int dum = 0;
u8 dummy[4];
atapi_write(drive, &dum, sizeof (dum));
len -= sizeof (dum);
atapi_write(drive, dummy, sizeof(dummy));
len -= sizeof(dummy);
}
/* Keep count of how much data we've moved. */
......@@ -1312,9 +1313,10 @@ static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *r
/* If we haven't moved enough data to satisfy the drive,
add some padding. */
while (len > thislen) {
int dum = 0;
atapi_read(drive, &dum, sizeof (dum));
len -= sizeof (dum);
u8 dummy[4];
atapi_read(drive, dummy, sizeof(dummy));
len -= sizeof(dummy);
}
/* Keep count of how much data we've moved. */
......@@ -1456,9 +1458,9 @@ static inline int cdrom_write_check_ireason(struct ata_device *drive, struct req
/* Throw some data at the drive so it doesn't hang
and quit this request. */
while (len > 0) {
int dum = 0;
atapi_write(drive, &dum, sizeof(dum));
len -= sizeof(dum);
u8 dummy[4];
atapi_write(drive, dummy, sizeof(dummy));
len -= sizeof(dummy);
}
} else {
/* Drive wants a command packet, or invalid ireason... */
......
/*
* linux/drivers/block/ide-features.c Version 0.04 June 9, 2000
*
* Copyright (C) 1999-2000 Linus Torvalds & authors (see below)
*
* Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
*
* Extracts if ide.c to address the evolving transfer rate code for
* the SETFEATURES_XFER callouts. Various parts of any given function
* are credited to previous ATA-IDE maintainers.
*
* Auto-CRC downgrade for Ultra DMA(ing)
*
* May be copied or modified under the terms of the GNU General Public License
*/
#include <linux/config.h>
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/genhd.h>
#include <linux/blkpg.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/bitops.h>
/*
* A Verbose noise maker for debugging on the attempted transfer rates.
*/
char *ide_xfer_verbose (byte xfer_rate)
{
static struct ide_xfer_par {
byte rate;
char *name;
} xfer_verbose[] = {
{ XFER_UDMA_7, "UDMA 7" },
{ XFER_UDMA_6, "UDMA 6" },
{ XFER_UDMA_5, "UDMA 5" },
{ XFER_UDMA_4, "UDMA 4" },
{ XFER_UDMA_3, "UDMA 3" },
{ XFER_UDMA_2, "UDMA 2" },
{ XFER_UDMA_1, "UDMA 1" },
{ XFER_UDMA_0, "UDMA 0" },
{ XFER_MW_DMA_2, "MW DMA 2" },
{ XFER_MW_DMA_1, "MW DMA 1" },
{ XFER_MW_DMA_0, "MW DMA 0" },
{ XFER_SW_DMA_2, "SW DMA 2" },
{ XFER_SW_DMA_1, "SW DMA 1" },
{ XFER_SW_DMA_0, "SW DMA 0" },
{ XFER_PIO_4, "PIO 4" },
{ XFER_PIO_3, "PIO 3" },
{ XFER_PIO_2, "PIO 2" },
{ XFER_PIO_1, "PIO 1" },
{ XFER_PIO_0, "PIO 0" },
{ XFER_PIO_SLOW, "PIO SLOW" },
};
int i = 0;
for (; i < ARRAY_SIZE(xfer_verbose); i++)
if (xfer_verbose[i].rate == xfer_rate)
return xfer_verbose[i].name;
return "XFER ERROR";
}
/*
* hd_driveid data come as little endian,
* they need to be converted on big endian machines
*/
void ide_fix_driveid(struct hd_driveid *id)
{
#ifndef __LITTLE_ENDIAN
# ifdef __BIG_ENDIAN
int i;
unsigned short *stringcast;
id->config = __le16_to_cpu(id->config);
id->cyls = __le16_to_cpu(id->cyls);
id->reserved2 = __le16_to_cpu(id->reserved2);
id->heads = __le16_to_cpu(id->heads);
id->track_bytes = __le16_to_cpu(id->track_bytes);
id->sector_bytes = __le16_to_cpu(id->sector_bytes);
id->sectors = __le16_to_cpu(id->sectors);
id->vendor0 = __le16_to_cpu(id->vendor0);
id->vendor1 = __le16_to_cpu(id->vendor1);
id->vendor2 = __le16_to_cpu(id->vendor2);
stringcast = (unsigned short *)&id->serial_no[0];
for (i = 0; i < (20/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
id->buf_type = __le16_to_cpu(id->buf_type);
id->buf_size = __le16_to_cpu(id->buf_size);
id->ecc_bytes = __le16_to_cpu(id->ecc_bytes);
stringcast = (unsigned short *)&id->fw_rev[0];
for (i = 0; i < (8/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
stringcast = (unsigned short *)&id->model[0];
for (i = 0; i < (40/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
id->dword_io = __le16_to_cpu(id->dword_io);
id->reserved50 = __le16_to_cpu(id->reserved50);
id->field_valid = __le16_to_cpu(id->field_valid);
id->cur_cyls = __le16_to_cpu(id->cur_cyls);
id->cur_heads = __le16_to_cpu(id->cur_heads);
id->cur_sectors = __le16_to_cpu(id->cur_sectors);
id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0);
id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1);
id->lba_capacity = __le32_to_cpu(id->lba_capacity);
id->dma_1word = __le16_to_cpu(id->dma_1word);
id->dma_mword = __le16_to_cpu(id->dma_mword);
id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
id->eide_dma_min = __le16_to_cpu(id->eide_dma_min);
id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
id->eide_pio = __le16_to_cpu(id->eide_pio);
id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
for (i = 0; i < 2; i++)
id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
for (i = 0; i < 4; i++)
id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
id->queue_depth = __le16_to_cpu(id->queue_depth);
for (i = 0; i < 4; i++)
id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
id->major_rev_num = __le16_to_cpu(id->major_rev_num);
id->minor_rev_num = __le16_to_cpu(id->minor_rev_num);
id->command_set_1 = __le16_to_cpu(id->command_set_1);
id->command_set_2 = __le16_to_cpu(id->command_set_2);
id->cfsse = __le16_to_cpu(id->cfsse);
id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1);
id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2);
id->csf_default = __le16_to_cpu(id->csf_default);
id->dma_ultra = __le16_to_cpu(id->dma_ultra);
id->word89 = __le16_to_cpu(id->word89);
id->word90 = __le16_to_cpu(id->word90);
id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues);
id->word92 = __le16_to_cpu(id->word92);
id->hw_config = __le16_to_cpu(id->hw_config);
id->acoustic = __le16_to_cpu(id->acoustic);
for (i = 0; i < 5; i++)
id->words95_99[i] = __le16_to_cpu(id->words95_99[i]);
id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
for (i = 0; i < 22; i++)
id->words104_125[i] = __le16_to_cpu(id->words104_125[i]);
id->last_lun = __le16_to_cpu(id->last_lun);
id->word127 = __le16_to_cpu(id->word127);
id->dlf = __le16_to_cpu(id->dlf);
id->csfo = __le16_to_cpu(id->csfo);
for (i = 0; i < 26; i++)
id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
id->word156 = __le16_to_cpu(id->word156);
for (i = 0; i < 3; i++)
id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
id->cfa_power = __le16_to_cpu(id->cfa_power);
for (i = 0; i < 14; i++)
id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
for (i = 0; i < 31; i++)
id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
for (i = 0; i < 48; i++)
id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
id->integrity_word = __le16_to_cpu(id->integrity_word);
# else
# error "Please fix <asm/byteorder.h>"
# endif
#endif
}
int ide_driveid_update(struct ata_device *drive)
{
/*
* Re-read drive->id for possible DMA mode
* change (copied from ide-probe.c)
*/
struct hd_driveid *id;
unsigned long timeout, flags;
SELECT_MASK(drive->channel, drive, 1);
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
mdelay(50);
OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG);
timeout = jiffies + WAIT_WORSTCASE;
do {
if (time_after(jiffies, timeout)) {
SELECT_MASK(drive->channel, drive, 0);
return 0; /* drive timed-out */
}
mdelay(50); /* give drive a breather */
} while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT);
mdelay(50); /* wait for IRQ and DRQ_STAT */
if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) {
SELECT_MASK(drive->channel, drive, 0);
printk("%s: CHECK for good STATUS\n", drive->name);
return 0;
}
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only; some systems need this */
SELECT_MASK(drive->channel, drive, 0);
id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
if (!id) {
__restore_flags(flags); /* local CPU only */
return 0;
}
ata_read(drive, id, SECTOR_WORDS);
GET_STAT(); /* clear drive IRQ */
ide__sti(); /* local CPU only */
__restore_flags(flags); /* local CPU only */
ide_fix_driveid(id);
if (id) {
drive->id->dma_ultra = id->dma_ultra;
drive->id->dma_mword = id->dma_mword;
drive->id->dma_1word = id->dma_1word;
/* anything more ? */
kfree(id);
}
return 1;
}
/*
* All hosts that use the 80c ribbon must use this!
*/
byte eighty_ninty_three(struct ata_device *drive)
{
return ((byte) ((drive->channel->udma_four) &&
#ifndef CONFIG_IDEDMA_IVB
(drive->id->hw_config & 0x4000) &&
#endif
(drive->id->hw_config & 0x6000)) ? 1 : 0);
}
/*
* Similar to ide_wait_stat(), except it never calls ide_error internally.
* This is a kludge to handle the new ide_config_drive_speed() function,
* and should not otherwise be used anywhere. Eventually, the tuneproc's
* should be updated to return ide_startstop_t, in which case we can get
* rid of this abomination again. :) -ml
*
* It is gone..........
*
* const char *msg == consider adding for verbose errors.
*/
int ide_config_drive_speed(struct ata_device *drive, byte speed)
{
struct ata_channel *hwif = drive->channel;
int i;
int error = 1;
u8 stat;
#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__)
u8 unit = (drive->select.b.unit & 0x01);
outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
#endif
/*
* Don't use ide_wait_cmd here - it will
* attempt to set_geometry and recalibrate,
* but for some reason these don't work at
* this point (lost interrupt).
*/
/*
* Select the drive, and issue the SETFEATURES command
*/
disable_irq(hwif->irq); /* disable_irq_nosync ?? */
udelay(1);
SELECT_DRIVE(drive->channel, drive);
SELECT_MASK(drive->channel, drive, 0);
udelay(1);
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
OUT_BYTE(speed, IDE_NSECTOR_REG);
OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
udelay(1);
/*
* Wait for drive to become non-BUSY
*/
if ((stat = GET_STAT()) & BUSY_STAT) {
unsigned long flags, timeout;
__save_flags(flags); /* local CPU only */
ide__sti(); /* local CPU only -- for jiffies */
timeout = jiffies + WAIT_CMD;
while ((stat = GET_STAT()) & BUSY_STAT) {
if (0 < (signed long)(jiffies - timeout))
break;
}
__restore_flags(flags); /* local CPU only */
}
/*
* Allow status to settle, then read it again.
* A few rare drives vastly violate the 400ns spec here,
* so we'll wait up to 10usec for a "good" status
* rather than expensively fail things immediately.
* This fix courtesy of Matthew Faupel & Niccolo Rigacci.
*/
for (i = 0; i < 10; i++) {
udelay(1);
if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
error = 0;
break;
}
}
SELECT_MASK(drive->channel, drive, 0);
enable_irq(hwif->irq);
if (error) {
ide_dump_status(drive, NULL, "set_drive_speed_status", stat);
return error;
}
drive->id->dma_ultra &= ~0xFF00;
drive->id->dma_mword &= ~0x0F00;
drive->id->dma_1word &= ~0x0F00;
#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__)
if (speed > XFER_PIO_4) {
outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
} else {
outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
}
#endif
switch(speed) {
case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break;
case XFER_UDMA_6: drive->id->dma_ultra |= 0x4040; break;
case XFER_UDMA_5: drive->id->dma_ultra |= 0x2020; break;
case XFER_UDMA_4: drive->id->dma_ultra |= 0x1010; break;
case XFER_UDMA_3: drive->id->dma_ultra |= 0x0808; break;
case XFER_UDMA_2: drive->id->dma_ultra |= 0x0404; break;
case XFER_UDMA_1: drive->id->dma_ultra |= 0x0202; break;
case XFER_UDMA_0: drive->id->dma_ultra |= 0x0101; break;
case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break;
case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break;
case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break;
case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break;
case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break;
case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break;
default: break;
}
return error;
}
EXPORT_SYMBOL(ide_fix_driveid);
EXPORT_SYMBOL(ide_driveid_update);
EXPORT_SYMBOL(eighty_ninty_three);
EXPORT_SYMBOL(ide_config_drive_speed);
/*
* Sun Feb 24 23:13:03 CET 2002: Patch by Andries Brouwer to remove the
* confused CMOS probe applied. This is solving more problems than it may
* (unexpectedly) introduce.
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/ide.h>
#include <linux/mc146818rtc.h>
#include <asm/io.h>
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
extern struct ata_device * get_info_ptr(kdev_t);
/*
* If heads is nonzero: find a translation with this many heads and S=63.
* Otherwise: find out how OnTrack Disk Manager would translate the disk.
*/
static void
ontrack(struct ata_device *drive, int heads, unsigned int *c, int *h, int *s)
{
static const u8 dm_head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0};
const u8 *headp = dm_head_vals;
unsigned long total;
/*
* The specs say: take geometry as obtained from Identify, compute
* total capacity C*H*S from that, and truncate to 1024*255*63. Now
* take S=63, H the first in the sequence 4, 8, 16, 32, 64, 128, 255
* such that 63*H*1024 >= total. [Please tell aeb@cwi.nl in case this
* computes a geometry different from what OnTrack uses.]
*/
total = ata_capacity(drive);
*s = 63;
if (heads) {
*h = heads;
*c = total / (63 * heads);
return;
}
while (63 * headp[0] * 1024 < total && headp[1] != 0)
headp++;
*h = headp[0];
*c = total / (63 * headp[0]);
}
/*
* This routine is called from the partition-table code in pt/msdos.c.
* It has two tasks:
* (i) to handle Ontrack DiskManager by offsetting everything by 63 sectors,
* or to handle EZdrive by remapping sector 0 to sector 1.
* (ii) to invent a translated geometry.
* Part (i) is suppressed if the user specifies the "noremap" option
* on the command line.
* Part (ii) is suppressed if the user specifies an explicit geometry.
*
* The ptheads parameter is either 0 or tells about the number of
* heads shown by the end of the first nonempty partition.
* If this is either 16, 32, 64, 128, 240 or 255 we'll believe it.
*
* The xparm parameter has the following meaning:
* 0 = convert to CHS with fewer than 1024 cyls
* using the same method as Ontrack DiskManager.
* 1 = same as "0", plus offset everything by 63 sectors.
* -1 = similar to "0", plus redirect sector 0 to sector 1.
* 2 = convert to a CHS geometry with "ptheads" heads.
*
* Returns 0 if the translation was not possible, if the device was not
* an IDE disk drive, or if a geometry was "forced" on the commandline.
* Returns 1 if the geometry translation was successful.
*/
int ide_xlate_1024(kdev_t i_rdev, int xparm, int ptheads, const char *msg)
{
struct ata_device *drive;
const char *msg1 = "";
int heads = 0;
int c, h, s;
int transl = 1; /* try translation */
int ret = 0;
drive = get_info_ptr(i_rdev);
if (!drive)
return 0;
/* remap? */
if (drive->remap_0_to_1 != 2) {
if (xparm == 1) { /* DM */
drive->sect0 = 63;
msg1 = " [remap +63]";
ret = 1;
} else if (xparm == -1) { /* EZ-Drive */
if (drive->remap_0_to_1 == 0) {
drive->remap_0_to_1 = 1;
msg1 = " [remap 0->1]";
ret = 1;
}
}
}
/* There used to be code here that assigned drive->id->CHS
to drive->CHS and that to drive->bios_CHS. However,
some disks have id->C/H/S = 4092/16/63 but are larger than 2.1 GB.
In such cases that code was wrong. Moreover,
there seems to be no reason to do any of these things. */
/* translate? */
if (drive->forced_geom)
transl = 0;
/* does ptheads look reasonable? */
if (ptheads == 32 || ptheads == 64 || ptheads == 128 ||
ptheads == 240 || ptheads == 255)
heads = ptheads;
if (xparm == 2) {
if (!heads ||
(drive->bios_head >= heads && drive->bios_sect == 63))
transl = 0;
}
if (xparm == -1) {
if (drive->bios_head > 16)
transl = 0; /* we already have a translation */
}
if (transl) {
ontrack(drive, heads, &c, &h, &s);
drive->bios_cyl = c;
drive->bios_head = h;
drive->bios_sect = s;
ret = 1;
}
drive->part[0].nr_sects = ata_capacity(drive);
if (ret)
printk("%s%s [%d/%d/%d]", msg, msg1,
drive->bios_cyl, drive->bios_head, drive->bios_sect);
return ret;
}
#endif
......@@ -977,7 +977,6 @@ int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg)
/* FIXME: what about the setup for the drive?! */
if (drive->channel->speedproc)
drive->channel->speedproc(drive, pio);
ide_driveid_update(drive);
}
abort:
......
......@@ -219,31 +219,6 @@ static void init_hwif_data(struct ata_channel *ch, unsigned int index)
extern struct block_device_operations ide_fops[];
/*
* This is called exactly *once* for each channel.
*/
void ide_geninit(struct ata_channel *ch)
{
unsigned int unit;
struct gendisk *gd = ch->gd;
for (unit = 0; unit < MAX_DRIVES; ++unit) {
struct ata_device *drive = &ch->drives[unit];
if (!drive->present)
continue;
if (drive->type != ATA_DISK && drive->type != ATA_FLOPPY)
continue;
register_disk(gd,mk_kdev(ch->major,unit<<PARTN_BITS),
#ifdef CONFIG_BLK_DEV_ISAPNP
(drive->forced_geom && drive->noprobe) ? 1 :
#endif
1 << PARTN_BITS, ide_fops, ata_capacity(drive));
}
}
/*
* Returns the (struct ata_device *) for a given device number. Return
* NULL if the given device number does not match any present drives.
......@@ -303,7 +278,10 @@ int ata_revalidate(kdev_t i_rdev)
if (!res) {
if (ata_ops(drive) && ata_ops(drive)->revalidate) {
ata_get(ata_ops(drive));
/* this is a no-op for tapes and SCSI based access */
/* This is expected to be a no-op for tapes and SCSI
* based access.
*/
ata_ops(drive)->revalidate(drive);
ata_put(ata_ops(drive));
} else
......@@ -312,6 +290,7 @@ int ata_revalidate(kdev_t i_rdev)
drive->busy = 0;
wake_up(&drive->wqueue);
MOD_DEC_USE_COUNT;
return res;
......@@ -359,6 +338,9 @@ void ide_driver_module(void)
revalidate_drives();
}
/*
* Release the data associated with a channel.
*/
void ide_unregister(struct ata_channel *ch)
{
struct gendisk *gd;
......@@ -614,7 +596,7 @@ static struct ata_operations * subdriver_iterator(struct ata_operations *prev)
/*
* Register an IDE interface, specifing exactly the registers etc
* Set init=1 iff calling before probes have taken place.
* Set initializing=1 iff calling before probes have taken place.
*/
int ide_register_hw(hw_regs_t *hw)
{
......@@ -776,80 +758,8 @@ static void __init init_global_data(void)
* 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".
*
* "hdx=noprobe" : drive may be present, but do not probe for it
* "hdx=none" : drive is NOT present, ignore cmos and do not probe
* "hdx=nowerr" : ignore the WRERR_STAT bit on this drive
* "hdx=cdrom" : drive is present, and is a cdrom drive
* "hdx=cyl,head,sect" : disk drive is present, with specified geometry
* "hdx=noremap" : do not remap 0->1 even though EZD was detected
* "hdx=autotune" : driver will attempt to tune interface speed
* to the fastest PIO mode supported,
* if possible for this drive only.
* Not fully supported by all chipset types,
* and quite likely to cause trouble with
* older/odd IDE drives.
*
* "hdx=slow" : insert a huge pause after each access to the data
* port. Should be used only as a last resort.
*
* "hdxlun=xx" : set the drive last logical unit.
* "hdx=flash" : allows for more than one ata_flash disk to be
* registered. In most cases, only one device
* will be present.
* "hdx=ide-scsi" : the return of the ide-scsi flag, this is useful for
* allowwing ide-floppy, ide-tape, and ide-cdrom|writers
* to use ide-scsi emulation on a device specific option.
* "idebus=xx" : inform IDE driver of VESA/PCI bus speed in MHz,
* where "xx" is between 20 and 66 inclusive,
* used when tuning chipset PIO modes.
* For PCI bus, 25 is correct for a P75 system,
* 30 is correct for P90,P120,P180 systems,
* and 33 is used for P100,P133,P166 systems.
* If in doubt, use idebus=33 for PCI.
* 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 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
* "idex=base,ctl,irq" : specify base, ctl, and irq number
* "idex=autotune" : driver will attempt to tune interface speed
* to the fastest PIO mode supported,
* for all drives on this interface.
* Not fully supported by all chipset types,
* and quite likely to cause trouble with
* older/odd IDE drives.
* "idex=noautotune" : driver will NOT attempt to tune interface speed
* This is the default for most chipsets,
* except the cmd640.
* "idex=serialize" : do not overlap operations on idex and ide(x^1)
* "idex=four" : four drives on idex and ide(x^1) share same ports
* "idex=reset" : reset interface before first use
* "idex=dma" : enable DMA by default on both drives if possible
* "idex=ata66" : informs the interface that it has an 80c cable
* for chipsets that are ATA-66 capable, but
* the ablity to bit test for detection is
* currently unknown.
* "ide=reverse" : Formerly called to pci sub-system, but now local.
*
* The following are valid ONLY on ide0, (except dc4030)
* and the defaults for the base,ctl ports must not be altered.
*
* "ide0=dtc2278" : probe/support DTC2278 interface
* "ide0=ht6560b" : probe/support HT6560B interface
* "ide0=cmd640_vlb" : *REQUIRED* for VLB cards with the CMD640 chip
* (not for PCI -- automatically detected)
* "ide0=qd65xx" : probe/support qd65xx interface
* "ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439, M1443, M1445)
* "ide0=umc8672" : probe/support umc8672 chipsets
* "idex=dc4030" : probe/support Promise DC4030VL interface
* "ide=doubler" : probe/support IDE doublers on Amiga
* Please look at Documentation/ide.txt to see the complete list of supported
* options.
*/
int __init ide_setup(char *s)
{
......@@ -1098,14 +1008,14 @@ int __init ide_setup(char *s)
case -6: /* dma */
ch->autodma = 1;
goto done;
case -5: /* "reset" */
case -5: /* reset */
ch->reset = 1;
goto done;
case -4: /* "noautotune" */
case -4: /* noautotune */
ch->drives[0].autotune = 2;
ch->drives[1].autotune = 2;
goto done;
case -3: /* "autotune" */
case -3: /* autotune */
ch->drives[0].autotune = 1;
ch->drives[1].autotune = 1;
goto done;
......@@ -1167,21 +1077,21 @@ int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driv
{
unsigned long flags;
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
/* FIXME: The locking here doesn't make the slightest sense! */
spin_lock_irqsave(&ide_lock, flags);
if (!drive->present || drive->driver != NULL || drive->busy || drive->usage) {
restore_flags(flags); /* all CPUs */
spin_unlock_irqrestore(&ide_lock, flags);
return 1;
}
/* FIXME: This will be pushed to the drivers! Thus allowing us to
* save one parameter here separate this out.
* save one parameter here and to separate this out.
*/
drive->driver = driver;
restore_flags(flags); /* all CPUs */
/* FIXME: Check what this magic number is supposed to be about? */
spin_unlock_irqrestore(&ide_lock, flags);
/* Default autotune or requested autotune */
if (drive->autotune != 2) {
if (drive->channel->XXX_udma) {
......@@ -1380,11 +1290,9 @@ static struct notifier_block ata_notifier = {
*/
static int __init ata_module_init(void)
{
int h;
printk(KERN_INFO "ATA/ATAPI device driver v" VERSION "\n");
ide_devfs_handle = devfs_mk_dir (NULL, "ide", NULL);
ide_devfs_handle = devfs_mk_dir(NULL, "ata", NULL);
/*
* Because most of the ATA adapters represent the timings in unit of
......@@ -1583,12 +1491,6 @@ static int __init ata_module_init(void)
initializing = 0;
for (h = 0; h < MAX_HWIFS; ++h) {
struct ata_channel *channel = &ide_hwifs[h];
if (channel->present)
ide_geninit(channel);
}
register_reboot_notifier(&ata_notifier);
return 0;
......
......@@ -53,8 +53,6 @@
#define PDC202XX_DEBUG_DRIVE_INFO 0
#define PDC202XX_DECODE_REGISTER_INFO 0
extern char *ide_xfer_verbose (byte xfer_rate);
/* A Register */
#define SYNC_ERRDY_EN 0xC0
......@@ -276,12 +274,12 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
drive->current_speed = speed;
#if PDC202XX_DEBUG_DRIVE_INFO
printk("%s: %s drive%d 0x%08x ",
drive->name, ide_xfer_verbose(speed),
printk("%s: %02x drive%d 0x%08x ",
drive->name, speed,
drive->dn, drive_conf);
pci_read_config_dword(dev, drive_pci, &drive_conf);
printk("0x%08x\n", drive_conf);
#endif /* PDC202XX_DEBUG_DRIVE_INFO */
#endif
return ide_config_drive_speed(drive, speed);
}
......
......@@ -8,22 +8,11 @@
*
* See linux/MAINTAINERS for address of current maintainer.
*
* This is the IDE probe module, as evolved from hd.c and ide.c.
*
* Version 1.00 move drive probing code from ide.c to ide-probe.c
* Version 1.01 fix compilation problem for m68k
* Version 1.02 increase WAIT_PIDENTIFY to avoid CD-ROM locking at boot
* by Andrea Arcangeli
* Version 1.03 fix for (hwif->chipset == ide_4drives)
* Version 1.04 fixed buggy treatments of known flash memory cards
*
* Version 1.05 fix for (hwif->chipset == ide_pdc4030)
* added ide6/7/8/9
* allowed for secondary flash card to be detectable
* 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.
*/
/*
* This is roughly the code related to device detection and
* device id handling.
*/
#include <linux/config.h>
......@@ -48,6 +37,366 @@
#include <asm/uaccess.h>
#include <asm/io.h>
extern struct ata_device * get_info_ptr(kdev_t);
/*
* This is called from the partition-table code in pt/msdos.c.
*
* It has two tasks:
*
* (I) to handle Ontrack DiskManager by offsetting everything by 63 sectors,
* or to handle EZdrive by remapping sector 0 to sector 1.
*
* (II) to invent a translated geometry.
*
* Part (I) is suppressed if the user specifies the "noremap" option
* on the command line.
*
* Part (II) is suppressed if the user specifies an explicit geometry.
*
* The ptheads parameter is either 0 or tells about the number of
* heads shown by the end of the first nonempty partition.
* If this is either 16, 32, 64, 128, 240 or 255 we'll believe it.
*
* The xparm parameter has the following meaning:
* 0 = convert to CHS with fewer than 1024 cyls
* using the same method as Ontrack DiskManager.
* 1 = same as "0", plus offset everything by 63 sectors.
* -1 = similar to "0", plus redirect sector 0 to sector 1.
* 2 = convert to a CHS geometry with "ptheads" heads.
*
* Returns 0 if the translation was not possible, if the device was not
* an IDE disk drive, or if a geometry was "forced" on the commandline.
* Returns 1 if the geometry translation was successful.
*/
int ide_xlate_1024(kdev_t i_rdev, int xparm, int ptheads, const char *msg)
{
struct ata_device *drive;
const char *msg1 = "";
int heads = 0;
int c, h, s;
int transl = 1; /* try translation */
int ret = 0;
drive = get_info_ptr(i_rdev);
if (!drive)
return 0;
/* remap? */
if (drive->remap_0_to_1 != 2) {
if (xparm == 1) { /* DM */
drive->sect0 = 63;
msg1 = " [remap +63]";
ret = 1;
} else if (xparm == -1) { /* EZ-Drive */
if (drive->remap_0_to_1 == 0) {
drive->remap_0_to_1 = 1;
msg1 = " [remap 0->1]";
ret = 1;
}
}
}
/* There used to be code here that assigned drive->id->CHS
to drive->CHS and that to drive->bios_CHS. However, some disks have
id->C/H/S = 4092/16/63 but are larger than 2.1 GB. In such cases
that code was wrong. Moreover, there seems to be no reason to do
any of these things. */
/* translate? */
if (drive->forced_geom)
transl = 0;
/* does ptheads look reasonable? */
if (ptheads == 32 || ptheads == 64 || ptheads == 128 ||
ptheads == 240 || ptheads == 255)
heads = ptheads;
if (xparm == 2) {
if (!heads ||
(drive->bios_head >= heads && drive->bios_sect == 63))
transl = 0;
}
if (xparm == -1) {
if (drive->bios_head > 16)
transl = 0; /* we already have a translation */
}
if (transl) {
static const u8 dm_head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0};
const u8 *headp = dm_head_vals;
unsigned long total;
/*
* If heads is nonzero: find a translation with this many heads
* and S=63. Otherwise: find out how OnTrack Disk Manager
* would translate the disk.
*
* The specs say: take geometry as obtained from Identify,
* compute total capacity C*H*S from that, and truncate to
* 1024*255*63. Now take S=63, H the first in the sequence 4,
* 8, 16, 32, 64, 128, 255 such that 63*H*1024 >= total.
* [Please tell aeb@cwi.nl in case this computes a geometry
* different from what OnTrack uses.]
*/
total = ata_capacity(drive);
s = 63;
if (heads) {
h = heads;
c = total / (63 * heads);
} else {
while (63 * headp[0] * 1024 < total && headp[1] != 0)
headp++;
h = headp[0];
c = total / (63 * headp[0]);
}
drive->bios_cyl = c;
drive->bios_head = h;
drive->bios_sect = s;
ret = 1;
}
drive->part[0].nr_sects = ata_capacity(drive);
if (ret)
printk("%s%s [%d/%d/%d]", msg, msg1,
drive->bios_cyl, drive->bios_head, drive->bios_sect);
return ret;
}
/*
* hd_driveid data come as little endian, it needs to be converted on big
* endian machines.
*/
void ata_fix_driveid(struct hd_driveid *id)
{
#ifndef __LITTLE_ENDIAN
# ifdef __BIG_ENDIAN
int i;
u16 *stringcast;
id->config = __le16_to_cpu(id->config);
id->cyls = __le16_to_cpu(id->cyls);
id->reserved2 = __le16_to_cpu(id->reserved2);
id->heads = __le16_to_cpu(id->heads);
id->track_bytes = __le16_to_cpu(id->track_bytes);
id->sector_bytes = __le16_to_cpu(id->sector_bytes);
id->sectors = __le16_to_cpu(id->sectors);
id->vendor0 = __le16_to_cpu(id->vendor0);
id->vendor1 = __le16_to_cpu(id->vendor1);
id->vendor2 = __le16_to_cpu(id->vendor2);
stringcast = (u16 *)&id->serial_no[0];
for (i = 0; i < (20/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
id->buf_type = __le16_to_cpu(id->buf_type);
id->buf_size = __le16_to_cpu(id->buf_size);
id->ecc_bytes = __le16_to_cpu(id->ecc_bytes);
stringcast = (u16 *)&id->fw_rev[0];
for (i = 0; i < (8/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
stringcast = (u16 *)&id->model[0];
for (i = 0; i < (40/2); i++)
stringcast[i] = __le16_to_cpu(stringcast[i]);
id->dword_io = __le16_to_cpu(id->dword_io);
id->reserved50 = __le16_to_cpu(id->reserved50);
id->field_valid = __le16_to_cpu(id->field_valid);
id->cur_cyls = __le16_to_cpu(id->cur_cyls);
id->cur_heads = __le16_to_cpu(id->cur_heads);
id->cur_sectors = __le16_to_cpu(id->cur_sectors);
id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0);
id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1);
id->lba_capacity = __le32_to_cpu(id->lba_capacity);
id->dma_1word = __le16_to_cpu(id->dma_1word);
id->dma_mword = __le16_to_cpu(id->dma_mword);
id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
id->eide_dma_min = __le16_to_cpu(id->eide_dma_min);
id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
id->eide_pio = __le16_to_cpu(id->eide_pio);
id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
for (i = 0; i < 2; ++i)
id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
for (i = 0; i < 4; ++i)
id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
id->queue_depth = __le16_to_cpu(id->queue_depth);
for (i = 0; i < 4; ++i)
id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
id->major_rev_num = __le16_to_cpu(id->major_rev_num);
id->minor_rev_num = __le16_to_cpu(id->minor_rev_num);
id->command_set_1 = __le16_to_cpu(id->command_set_1);
id->command_set_2 = __le16_to_cpu(id->command_set_2);
id->cfsse = __le16_to_cpu(id->cfsse);
id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1);
id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2);
id->csf_default = __le16_to_cpu(id->csf_default);
id->dma_ultra = __le16_to_cpu(id->dma_ultra);
id->word89 = __le16_to_cpu(id->word89);
id->word90 = __le16_to_cpu(id->word90);
id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues);
id->word92 = __le16_to_cpu(id->word92);
id->hw_config = __le16_to_cpu(id->hw_config);
id->acoustic = __le16_to_cpu(id->acoustic);
for (i = 0; i < 5; i++)
id->words95_99[i] = __le16_to_cpu(id->words95_99[i]);
id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
for (i = 0; i < 22; i++)
id->words104_125[i] = __le16_to_cpu(id->words104_125[i]);
id->last_lun = __le16_to_cpu(id->last_lun);
id->word127 = __le16_to_cpu(id->word127);
id->dlf = __le16_to_cpu(id->dlf);
id->csfo = __le16_to_cpu(id->csfo);
for (i = 0; i < 26; i++)
id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
id->word156 = __le16_to_cpu(id->word156);
for (i = 0; i < 3; i++)
id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
id->cfa_power = __le16_to_cpu(id->cfa_power);
for (i = 0; i < 14; i++)
id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
for (i = 0; i < 31; i++)
id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
for (i = 0; i < 48; i++)
id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
id->integrity_word = __le16_to_cpu(id->integrity_word);
# else
# error "Please fix <asm/byteorder.h>"
# endif
#endif
}
/*
* All hosts that use the 80c ribbon must use this!
*/
byte eighty_ninty_three(struct ata_device *drive)
{
return ((u8) ((drive->channel->udma_four) &&
#ifndef CONFIG_IDEDMA_IVB
(drive->id->hw_config & 0x4000) &&
#endif
(drive->id->hw_config & 0x6000)) ? 1 : 0);
}
/*
* Similar to ide_wait_stat(), except it never calls ide_error internally.
* This is a kludge to handle the new ide_config_drive_speed() function,
* and should not otherwise be used anywhere. Eventually, the tuneproc's
* should be updated to return ide_startstop_t, in which case we can get
* rid of this abomination again. :) -ml
*
* It is gone..........
*
* const char *msg == consider adding for verbose errors.
*/
int ide_config_drive_speed(struct ata_device *drive, byte speed)
{
struct ata_channel *hwif = drive->channel;
int i;
int error = 1;
u8 stat;
#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__)
u8 unit = (drive->select.b.unit & 0x01);
outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
#endif
/*
* Don't use ide_wait_cmd here - it will attempt to set_geometry and
* recalibrate, but for some reason these don't work at this point
* (lost interrupt).
*/
/*
* Select the drive, and issue the SETFEATURES command
*/
disable_irq(hwif->irq); /* disable_irq_nosync ?? */
udelay(1);
SELECT_DRIVE(drive->channel, drive);
SELECT_MASK(drive->channel, drive, 0);
udelay(1);
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
OUT_BYTE(speed, IDE_NSECTOR_REG);
OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
udelay(1);
/*
* Wait for drive to become non-BUSY
*/
if ((stat = GET_STAT()) & BUSY_STAT) {
unsigned long flags, timeout;
__save_flags(flags); /* local CPU only */
ide__sti(); /* local CPU only -- for jiffies */
timeout = jiffies + WAIT_CMD;
while ((stat = GET_STAT()) & BUSY_STAT) {
if (time_after(jiffies, timeout))
break;
}
__restore_flags(flags); /* local CPU only */
}
/*
* Allow status to settle, then read it again.
* A few rare drives vastly violate the 400ns spec here,
* so we'll wait up to 10usec for a "good" status
* rather than expensively fail things immediately.
* This fix courtesy of Matthew Faupel & Niccolo Rigacci.
*/
for (i = 0; i < 10; i++) {
udelay(1);
if (OK_STAT((stat = GET_STAT()), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
error = 0;
break;
}
}
SELECT_MASK(drive->channel, drive, 0);
enable_irq(hwif->irq);
if (error) {
ide_dump_status(drive, NULL, "set_drive_speed_status", stat);
return error;
}
drive->id->dma_ultra &= ~0xFF00;
drive->id->dma_mword &= ~0x0F00;
drive->id->dma_1word &= ~0x0F00;
#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__)
if (speed > XFER_PIO_4) {
outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
} else {
outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
}
#endif
switch(speed) {
case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break;
case XFER_UDMA_6: drive->id->dma_ultra |= 0x4040; break;
case XFER_UDMA_5: drive->id->dma_ultra |= 0x2020; break;
case XFER_UDMA_4: drive->id->dma_ultra |= 0x1010; break;
case XFER_UDMA_3: drive->id->dma_ultra |= 0x0808; break;
case XFER_UDMA_2: drive->id->dma_ultra |= 0x0404; break;
case XFER_UDMA_1: drive->id->dma_ultra |= 0x0202; break;
case XFER_UDMA_0: drive->id->dma_ultra |= 0x0101; break;
case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break;
case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break;
case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break;
case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break;
case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break;
case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break;
default: break;
}
return error;
}
static inline void do_identify(struct ata_device *drive, u8 cmd)
{
int bswap = 1;
......@@ -70,7 +419,7 @@ static inline void do_identify(struct ata_device *drive, u8 cmd)
ata_read(drive, id, SECTOR_WORDS);
ide__sti(); /* local CPU only */
ide_fix_driveid(id);
ata_fix_driveid(id);
if (id->word156 == 0x4d42) {
printk("%s: drive->id->word156 == 0x%04x \n", drive->name, drive->id->word156);
......@@ -115,7 +464,7 @@ static inline void do_identify(struct ata_device *drive, u8 cmd)
* Check for an ATAPI device:
*/
if (cmd == WIN_PIDENTIFY) {
byte type = (id->config >> 8) & 0x1f;
u8 type = (id->config >> 8) & 0x1f;
printk("ATAPI ");
#ifdef CONFIG_BLK_DEV_PDC4030
if (drive->channel->unit == 1 && drive->channel->chipset == ide_pdc4030) {
......@@ -307,14 +656,13 @@ static int identify(struct ata_device *drive, u8 cmd)
/*
* do_probe() has the difficult job of finding a drive if it exists,
* without getting hung up if it doesn't exist, without trampling on
* ethernet cards, and without leaving any IRQs dangling to haunt us later.
* This has the difficult job of finding a drive if it exists, without getting
* hung up if it doesn't exist, without trampling on ethernet cards, and
* without leaving any IRQs dangling to haunt us later.
*
* If a drive is "known" to exist (from CMOS or kernel parameters),
* but does not respond right away, the probe will "hang in there"
* for the maximum wait time (about 30 seconds), otherwise it will
* exit much more quickly.
* If a drive is "known" to exist (from CMOS or kernel parameters), but does
* not respond right away, the probe will "hang in there" for the maximum wait
* time (about 30 seconds), otherwise it will exit much more quickly.
*
* Returns: 0 device was identified
* 1 device timed-out (no response to identify request)
......@@ -322,7 +670,7 @@ static int identify(struct ata_device *drive, u8 cmd)
* 3 bad status from device (possible for ATAPI drives)
* 4 probe was not attempted because failure was obvious
*/
static int do_probe(struct ata_device *drive, byte cmd)
static int do_probe(struct ata_device *drive, u8 cmd)
{
int rc;
struct ata_channel *hwif = drive->channel;
......@@ -372,70 +720,17 @@ static int do_probe(struct ata_device *drive, byte cmd)
if (drive->select.b.unit != 0) {
SELECT_DRIVE(hwif,&hwif->drives[0]); /* exit with drive0 selected */
mdelay(50);
(void) GET_STAT(); /* ensure drive irq is clear */
}
return rc;
}
static void enable_nest(struct ata_device *drive)
{
unsigned long timeout;
printk("%s: enabling %s -- ", drive->channel->name, drive->id->model);
SELECT_DRIVE(drive->channel, drive);
mdelay(50);
OUT_BYTE(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
timeout = jiffies + WAIT_WORSTCASE;
do {
if (time_after(jiffies, timeout)) {
printk("failed (timeout)\n");
return;
}
mdelay(50);
} while (GET_STAT() & BUSY_STAT);
mdelay(50);
if (!OK_STAT(GET_STAT(), 0, BAD_STAT))
printk("failed (status = 0x%02x)\n", GET_STAT());
else
printk("success\n");
if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */
(void) do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */
GET_STAT(); /* ensure drive irq is clear */
}
}
/*
* Tests for existence of a given drive using do_probe().
*/
static inline void probe_for_drive(struct ata_device *drive)
{
if (drive->noprobe) /* skip probing? */
return;
if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */
do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */
}
if (drive->id && strstr(drive->id->model, "E X A B Y T E N E S T"))
enable_nest(drive);
if (!drive->present)
return; /* drive not found */
if (drive->id == NULL) { /* identification failed? */
if (drive->type == ATA_DISK) {
printk ("%s: non-IDE drive, CHS=%d/%d/%d\n",
drive->name, drive->cyl, drive->head, drive->sect);
} else if (drive->type == ATA_ROM) {
printk("%s: ATAPI cdrom (?)\n", drive->name);
} else {
drive->present = 0; /* nuke it */
}
}
return rc;
}
/*
* This routine only knows how to look for drive units 0 and 1
* on an interface, so any setting of MAX_DRIVES > 2 won't work here.
* Probe for drivers on a channel.
*
* This routine only knows how to look for drive units 0 and 1 on an interface,
* so any setting of MAX_DRIVES > 2 won't work here.
*/
static void channel_probe(struct ata_channel *ch)
{
......@@ -457,7 +752,52 @@ static void channel_probe(struct ata_channel *ch)
for (i = 0; i < MAX_DRIVES; ++i) {
struct ata_device *drive = &ch->drives[i];
probe_for_drive(drive);
if (drive->noprobe) /* don't look for this one */
continue;
if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */
do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */
}
/* Special handling of EXABYTE controller cards. */
if (drive->id && strstr(drive->id->model, "E X A B Y T E N E S T")) {
unsigned long timeout;
printk("%s: enabling %s -- ", drive->channel->name, drive->id->model);
SELECT_DRIVE(drive->channel, drive);
mdelay(50);
OUT_BYTE(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
timeout = jiffies + WAIT_WORSTCASE;
do {
if (time_after(jiffies, timeout)) {
printk("failed (timeout)\n");
return;
}
mdelay(50);
} while (GET_STAT() & BUSY_STAT);
mdelay(50);
if (!OK_STAT(GET_STAT(), 0, BAD_STAT))
printk("failed (status = 0x%02x)\n", GET_STAT());
else
printk("success\n");
if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */
do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */
}
}
if (!drive->present)
continue; /* drive not found */
if (!drive->id) { /* identification failed? */
if (drive->type == ATA_DISK)
printk ("%s: pre-ATA drive, CHS=%d/%d/%d\n",
drive->name, drive->cyl, drive->head, drive->sect);
else if (drive->type == ATA_ROM)
printk("%s: ATAPI cdrom (?)\n", drive->name);
else
drive->present = 0; /* nuke it */
}
/* drive found, there is a channel it is attached too. */
if (drive->present)
......@@ -518,9 +858,9 @@ static void channel_probe(struct ata_channel *ch)
device_register(&ch->dev);
if (ch->io_ports[IDE_CONTROL_OFFSET] && ch->reset) {
if (ch->reset && ch->io_ports[IDE_CONTROL_OFFSET]) {
unsigned long timeout = jiffies + WAIT_WORSTCASE;
byte stat;
u8 stat;
printk("%s: reset\n", ch->name);
OUT_BYTE(12, ch->io_ports[IDE_CONTROL_OFFSET]);
......@@ -763,7 +1103,7 @@ static void channel_init(struct ata_channel *ch)
}
#endif
if (devfs_register_blkdev (ch->major, ch->name, ide_fops)) {
if (devfs_register_blkdev(ch->major, ch->name, ide_fops)) {
printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", ch->name, ch->major);
return;
......@@ -791,8 +1131,7 @@ static void channel_init(struct ata_channel *ch)
printk(KERN_INFO "%s: probed IRQ %d failed, using default.\n", ch->name, ch->irq);
}
/* Initialize partition and global device data. ide_geninit() gets
* called somewhat later, during the partition check.
/* Initialize partition and global device data.
*/
gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
......@@ -873,7 +1212,13 @@ static void channel_init(struct ata_channel *ch)
printk(KERN_CRIT "(%s) Out of memory\n", __FUNCTION__);
}
int ideprobe_init (void)
/*
* FIXME: consider moving this to main.c, since this is the only place where
* it's used.
*
* Probe only for drives on channes which are not already present.
*/
int ideprobe_init(void)
{
unsigned int i;
int probe[MAX_HWIFS];
......@@ -884,12 +1229,19 @@ int ideprobe_init (void)
/*
* Probe for drives in the usual way.. CMOS/BIOS, then poke at ports
*/
for (i = 0; i < MAX_HWIFS; ++i)
if (probe[i])
channel_probe(&ide_hwifs[i]);
for (i = 0; i < MAX_HWIFS; ++i)
if (probe[i])
channel_init(&ide_hwifs[i]);
for (i = 0; i < MAX_HWIFS; ++i) {
if (!probe[i])
continue;
channel_probe(&ide_hwifs[i]);
}
for (i = 0; i < MAX_HWIFS; ++i) {
if (!probe[i])
continue;
channel_init(&ide_hwifs[i]);
}
return 0;
}
EXPORT_SYMBOL(ata_fix_driveid);
EXPORT_SYMBOL(eighty_ninty_three);
EXPORT_SYMBOL(ide_config_drive_speed);
......@@ -237,8 +237,6 @@ static byte svwks_proc;
#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
extern char *ide_xfer_verbose (byte xfer_rate);
static struct pci_dev *isa_dev;
static int svwks_ratemask(struct ata_device *drive)
......@@ -347,8 +345,8 @@ static int svwks_tune_chipset(struct ata_device *drive, byte speed)
#endif
#if SVWKS_DEBUG_DRIVE_INFO
printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
#endif /* SVWKS_DEBUG_DRIVE_INFO */
printk("%s: %02x drive%d\n", drive->name, speed, drive->dn);
#endif
pci_write_config_byte(dev, drive_pci, pio_timing);
if (csb5)
......
......@@ -403,11 +403,11 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
return p-buffer;
}
#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
byte sis_proc = 0;
extern char *ide_xfer_verbose (byte xfer_rate);
#endif
static int sis5513_ratemask(struct ata_device *drive)
{
......
......@@ -29,8 +29,6 @@
#include "ata-timing.h"
#include "pcihost.h"
extern char *ide_xfer_verbose (byte xfer_rate);
/*
* SL82C105 PCI config register 0x40 bits.
*/
......@@ -100,8 +98,9 @@ static void config_for_pio(struct ata_device *drive, int pio, int report)
pci_read_config_word(dev, reg, &drv_ctrl);
if (report) {
printk("%s: selected %s (%dns) (%04X)\n", drive->name,
ide_xfer_verbose(xfer_mode), t->cycle, drv_ctrl);
printk("%s: selected %02x (%dns) (%04X)\n",
drive->name, xfer_mode,
t->cycle, drv_ctrl);
}
}
}
......
......@@ -1265,7 +1265,7 @@ int isd200_get_inquiry_data( struct us_data *us )
/* ATA Command Identify successful */
int i;
__u16 *src, *dest;
ide_fix_driveid(&info->drive);
ata_fix_driveid(&info->drive);
US_DEBUGP(" Identify Data Structure:\n");
US_DEBUGP(" config = 0x%x\n", info->drive.config);
......
......@@ -224,15 +224,11 @@ void add_gd_partition(struct gendisk *hd, int minor, int start, int size)
static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor)
{
devfs_handle_t de = NULL;
static int first_time = 1;
unsigned long first_sector;
struct block_device *bdev;
char buf[64];
int i;
if (first_time)
printk(KERN_INFO "Partition check:\n");
first_time = 0;
first_sector = hd->part[minor(dev)].start_sect;
/*
......
......@@ -331,10 +331,13 @@ enum {
#define HDIO_GETGEO_BIG_RAW 0x0331 /* */
#define __NEW_HD_DRIVE_ID
/* structure returned by HDIO_GET_IDENTITY,
* as per ANSI NCITS ATA6 rev.1b spec
/*
* Structure returned by HDIO_GET_IDENTITY, as per ANSI NCITS ATA6 rev.1b spec.
*
* If you change something here, please remember to update fix_driveid() in
* ide/probe.c.
*/
/* if you change something here remember to update ide_fix_driveid() */
struct hd_driveid {
unsigned short config; /* lots of obsolete bit flags */
unsigned short cyls; /* Obsolete, "physical" cyls */
......
......@@ -762,7 +762,6 @@ extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *);
extern int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg);
extern void ide_fix_driveid(struct hd_driveid *id);
extern int ide_driveid_update(struct ata_device *);
extern int ide_config_drive_speed(struct ata_device *, byte);
extern byte eighty_ninty_three(struct ata_device *);
......@@ -893,11 +892,14 @@ extern void ide_release_dma(struct ata_channel *);
extern int ata_start_dma(struct ata_device *, struct request *rq);
extern void ata_init_dma(struct ata_channel *, unsigned long) __init;
#endif
extern void ata_fix_driveid(struct hd_driveid *);
extern spinlock_t ide_lock;
#define DRIVE_LOCK(drive) ((drive)->queue.queue_lock)
#define DRIVE_LOCK(drive) ((drive)->queue.queue_lock)
extern int drive_is_ready(struct ata_device *drive);
......
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