Commit c57f6cae authored by Martin Dalecki's avatar Martin Dalecki Committed by Jeff Garzik

[PATCH] 2.5.29 IDE 109

 - Include first cut by Adam J. Richter on proper lock protection for
   tuning functions.

 - Rename ide_register_subdriver() to ata_register_device() and
   ide_unregister_subdriver() accordingly to ata_unregister_device(),
   since this is reflecting better what those functions are about.

 - Remove tons of "curicum vite" style useless documentation here and
   there.
parent 3bd271cd
Information regarding the Enhanced IDE drive in Linux 2.5
==============================================================================
......@@ -301,6 +298,53 @@ There may be more options than shown -- use the source, Luke!
Everything else is rejected with a "BAD OPTION" message.
================================================================================
IDE ATAPI streaming tape driver
-------------------------------
This driver is a part of the Linux ide driver and works in co-operation
with linux/drivers/block/ide.c.
The driver, in co-operation with ide.c, basically traverses the
request-list for the block device interface. The character device
interface, on the other hand, creates new requests, adds them
to the request-list of the block device, and waits for their completion.
Pipelined operation mode is now supported on both reads and writes.
The block device major and minor numbers are determined from the
tape's relative position in the ide interfaces, as explained in ide.c.
The character device interface consists of the following devices:
ht0 major 37, minor 0 first IDE tape, rewind on close.
ht1 major 37, minor 1 second IDE tape, rewind on close.
...
nht0 major 37, minor 128 first IDE tape, no rewind on close.
nht1 major 37, minor 129 second IDE tape, no rewind on close.
...
Run linux/scripts/MAKEDEV.ide to create the above entries.
The general magnetic tape commands compatible interface, as defined by
include/linux/mtio.h, is accessible through the character device.
General ide driver configuration options, such as the interrupt-unmask
flag, can be configured by issuing an ioctl to the block device interface,
as any other ide device.
Our own ide-tape ioctl's can be issued to either the block device or
the character device interface.
Maximal throughput with minimal bus load will usually be achieved in the
following scenario:
1. ide-tape is operating in the pipelined operation mode.
2. No buffering is performed by the user backup program.
================================================================================
Some Terminology
......
......@@ -107,13 +107,14 @@ static inline void out_reg(u8 data, u8 reg)
* Set PIO mode for the specified drive.
* This function computes timing parameters
* and sets controller registers accordingly.
* It assumes IRQ's are disabled or at least that no other process will
* attempt to access the IDE registers concurrently.
*/
static void ali14xx_tune_drive(struct ata_device *drive, u8 pio)
{
int drive_num;
int time1, time2;
u8 param1, param2, param3, param4;
unsigned long flags;
struct ata_timing *t;
if (pio == 255)
......@@ -140,15 +141,12 @@ static void ali14xx_tune_drive(struct ata_device *drive, u8 pio)
/* stuff timing parameters into controller registers */
drive_num = (drive->channel->index << 1) + drive->select.b.unit;
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
outb_p(reg_on, base_port);
out_reg(param1, reg_tab[drive_num].reg1);
out_reg(param2, reg_tab[drive_num].reg2);
out_reg(param3, reg_tab[drive_num].reg3);
out_reg(param4, reg_tab[drive_num].reg4);
outb_p(reg_off, base_port);
restore_flags(flags); /* all CPUs */
}
/*
......
......@@ -66,21 +66,18 @@ static void sub22 (char b, char c)
}
}
/* Assumes IRQ's are disabled or at least that no other process will
attempt to access the IDE registers concurrently. */
static void tune_dtc2278(struct ata_device *drive, u8 pio)
{
unsigned long flags;
pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
if (pio >= 3) {
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
/*
* This enables PIO mode4 (3?) on the first interface
*/
sub22(1,0xc3);
sub22(0,0xa0);
restore_flags(flags); /* all CPUs */
} else {
/* we don't know how to set it back again.. */
}
......
......@@ -249,12 +249,8 @@ static u8 ht_pio2timings(struct ata_device *drive, u8 pio)
*/
static void ht_set_prefetch(struct ata_device *drive, u8 state)
{
unsigned long flags;
int t = HT_PREFETCH_MODE << 8;
save_flags (flags); /* all CPUs */
cli(); /* all CPUs */
/*
* Prefetch mode and unmask irq seems to conflict
*/
......@@ -267,16 +263,16 @@ static void ht_set_prefetch(struct ata_device *drive, u8 state)
drive->channel->no_unmask = 0;
}
restore_flags (flags); /* all CPUs */
#ifdef DEBUG
printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
#endif
}
/* Assumes IRQ's are disabled or at least that no other process will attempt to
* access the IDE registers concurrently.
*/
static void tune_ht6560b(struct ata_device *drive, u8 pio)
{
unsigned long flags;
u8 timing;
switch (pio) {
......@@ -288,14 +284,9 @@ static void tune_ht6560b(struct ata_device *drive, u8 pio)
timing = ht_pio2timings(drive, pio);
save_flags (flags); /* all CPUs */
cli(); /* all CPUs */
drive->drive_data &= 0xff00;
drive->drive_data |= timing;
restore_flags (flags); /* all CPUs */
#ifdef DEBUG
printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
#endif
......
......@@ -2915,7 +2915,7 @@ int ide_cdrom_cleanup(struct ata_device *drive)
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *devinfo = &info->devinfo;
if (ide_unregister_subdriver (drive))
if (ata_unregister_device(drive))
return 1;
if (info->buffer != NULL)
kfree(info->buffer);
......@@ -2974,7 +2974,7 @@ static void ide_cdrom_attach(struct ata_device *drive)
printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
return;
}
if (ide_register_subdriver (drive, &ide_cdrom_driver)) {
if (ata_register_device(drive, &ide_cdrom_driver)) {
printk(KERN_ERR "%s: Failed to register the driver with ide.c\n", drive->name);
kfree (info);
return;
......
......@@ -1279,7 +1279,7 @@ static int idedisk_cleanup(struct ata_device *drive)
printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
drive->name);
}
ret = ide_unregister_subdriver(drive);
ret = ata_unregister_device(drive);
/* FIXME: This is killing the kernel with BUG 185 at asm/spinlocks.h
* horribly. Check whatever we did REGISTER the device properly
......@@ -1471,8 +1471,8 @@ static void idedisk_attach(struct ata_device *drive)
if (req[0] != '\0' && strcmp(req, "ide-disk"))
return;
if (ide_register_subdriver(drive, &idedisk_driver)) {
printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name);
if (ata_register_device(drive, &idedisk_driver)) {
printk(KERN_ERR "%s: Failed to register the driver with ide.c\n", drive->name);
return;
}
......
......@@ -1723,10 +1723,10 @@ static int idefloppy_cleanup(struct ata_device *drive)
{
idefloppy_floppy_t *floppy = drive->driver_data;
if (ide_unregister_subdriver (drive))
if (ata_unregister_device(drive))
return 1;
drive->driver_data = NULL;
kfree (floppy);
kfree(floppy);
return 0;
}
......@@ -1780,7 +1780,7 @@ static void idefloppy_attach(struct ata_device *drive)
drive->name);
return;
}
if (ide_register_subdriver(drive, &idefloppy_driver)) {
if (ata_register_device(drive, &idefloppy_driver)) {
printk(KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name);
kfree (floppy);
return;
......
This diff is collapsed.
......@@ -89,10 +89,7 @@ static void it8172_tune_drive (struct ata_device *drive, u8 pio)
drive_enables |= 0x0006;
}
save_flags(flags);
cli();
pci_write_config_word(dev, master_port, master_data);
restore_flags(flags);
}
#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IT8172_TUNING)
......
......@@ -365,7 +365,7 @@ void ide_unregister(struct ata_channel *ch)
if (ata_ops(drive)->cleanup(drive))
goto abort;
} else
ide_unregister_subdriver(drive);
ata_unregister_device(drive);
}
}
ch->present = 0;
......@@ -1037,10 +1037,7 @@ int __init ide_setup(char *s)
/****************************************************************************/
/*
* This is in fact registering a device not a driver.
*/
int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driver)
int ata_register_device(struct ata_device *drive, struct ata_operations *driver)
{
unsigned long flags;
......@@ -1052,12 +1049,9 @@ int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driv
return 1;
}
/* FIXME: This will be pushed to the drivers! Thus allowing us to
* save one parameter here and to separate this out.
*/
drive->driver = driver;
spin_unlock_irqrestore(&ide_lock, flags);
/* Default autotune or requested autotune */
if (drive->autotune != 2) {
struct ata_channel *ch = drive->channel;
......@@ -1071,11 +1065,13 @@ int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driv
* PARANOIA!!!
*/
spin_lock_irqsave(ch->lock, flags);
udma_enable(drive, 0, 0);
ch->udma_setup(drive, ch->modes_map);
#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
udma_tcq_enable(drive, 1);
#endif
spin_unlock_irqrestore(ch->lock, flags);
}
/* Only CD-ROMs and tape drives support DSC overlap. But only
......@@ -1103,13 +1099,8 @@ int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driv
*
* FIXME: Check whatever we maybe don't call it twice!.
*/
int ide_unregister_subdriver(struct ata_device *drive)
int ata_unregister_device(struct ata_device *drive)
{
#if 0
if (__MOD_IN_USE(ata_ops(drive)->owner))
return 1;
#endif
if (drive->usage || drive->busy || !ata_ops(drive))
return 1;
......@@ -1181,8 +1172,8 @@ EXPORT_SYMBOL(ide_lock);
devfs_handle_t ide_devfs_handle;
EXPORT_SYMBOL(ide_register_subdriver);
EXPORT_SYMBOL(ide_unregister_subdriver);
EXPORT_SYMBOL(ata_register_device);
EXPORT_SYMBOL(ata_unregister_device);
EXPORT_SYMBOL(ata_revalidate);
EXPORT_SYMBOL(ide_register_hw);
EXPORT_SYMBOL(ide_unregister);
......
......@@ -244,13 +244,15 @@ static void compute_clocks(int pio, pio_clocks_t *clks)
}
/* Main tune procedure, called from tuneproc. */
/* Main tune procedure, called from tuneproc.
Assumes IRQ's are disabled or at least that no other process will
attempt to access the IDE registers concurrently.
*/
static void opti621_tune_drive(struct ata_device *drive, u8 pio)
{
/* primary and secondary drives share some registers,
* so we have to program both drives
*/
unsigned long flags;
u8 pio1, pio2;
pio_clocks_t first, second;
int ax, drdy;
......@@ -281,9 +283,6 @@ static void opti621_tune_drive(struct ata_device *drive, u8 pio)
hwif->name, ax, second.data_time, second.recovery_time, drdy);
#endif
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
reg_base = hwif->io_ports[IDE_DATA_OFFSET];
outb(0xc0, reg_base+CNTRL_REG); /* allow Register-B */
outb(0xff, reg_base+5); /* hmm, setupvic.exe does this ;-) */
......@@ -306,8 +305,6 @@ static void opti621_tune_drive(struct ata_device *drive, u8 pio)
write_reg(misc, MISC_REG); /* set address setup, DRDY timings, */
/* and read prefetch for both drives */
restore_flags(flags); /* all CPUs */
}
/*
......
/*
* Copyright (C) 1996-2001 Linus Torvalds & author (see below)
*/
/*
*
* Version 0.03 Cleaned auto-tune, added probe
* Version 0.04 Added second channel tuning
* Version 0.05 Enhanced tuning ; added qd6500 support
......@@ -81,36 +79,12 @@
* bit 5 : status, but of what ?
* bit 6 : always set 1 by dos driver
* bit 7 : set 1 for non-ATAPI devices on primary port
* (maybe read-ahead and post-write buffer ?)
* (maybe read-ahead and post-write buffer ?)
*/
static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
static void qd_write_reg(u8 content, unsigned int reg)
{
unsigned long flags;
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
outb(content,reg);
restore_flags(flags); /* all CPUs */
}
static u8 __init qd_read_reg(unsigned int reg)
{
unsigned long flags;
u8 read;
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
read = inb(reg);
restore_flags(flags); /* all CPUs */
return read;
}
/*
* qd_select:
*
* This routine is invoked from ide.c to prepare for access to a given drive.
*/
......@@ -120,12 +94,10 @@ static void qd_select(struct ata_device *drive)
(QD_TIMREG(drive) & 0x02);
if (timings[index] != QD_TIMING(drive))
qd_write_reg(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
}
/*
* qd6500_compute_timing
*
* computes the timing value where
* lower nibble represents active time, in count of VLB clocks
* upper nibble represents recovery time, in count of VLB clocks
......@@ -147,8 +119,6 @@ static u8 qd6500_compute_timing(struct ata_channel *hwif, int active_time, int r
}
/*
* qd6580_compute_timing
*
* idem for qd6580
*/
......@@ -161,8 +131,6 @@ static u8 qd6580_compute_timing(int active_time, int recovery_time)
}
/*
* qd_find_disk_type
*
* tries to find timing from dos driver's table
*/
......@@ -187,8 +155,6 @@ static int qd_find_disk_type(struct ata_device *drive,
}
/*
* qd_timing_ok:
*
* check whether timings don't conflict
*/
......@@ -201,8 +167,6 @@ static int qd_timing_ok(struct ata_device drives[])
}
/*
* qd_set_timing:
*
* records the timing, and enables selectproc as needed
*/
......@@ -221,10 +185,6 @@ static void qd_set_timing(struct ata_device *drive, u8 timing)
printk(KERN_DEBUG "%s: %#x\n", drive->name, timing);
}
/*
* qd6500_tune_drive
*/
static void qd6500_tune_drive(struct ata_device *drive, u8 pio)
{
int active_time = 175;
......@@ -242,10 +202,6 @@ static void qd6500_tune_drive(struct ata_device *drive, u8 pio)
qd_set_timing(drive, qd6500_compute_timing(drive->channel, active_time, recovery_time));
}
/*
* qd6580_tune_drive
*/
static void qd6580_tune_drive(struct ata_device *drive, u8 pio)
{
struct ata_timing *t;
......@@ -291,7 +247,7 @@ static void qd6580_tune_drive(struct ata_device *drive, u8 pio)
}
if (!drive->channel->unit && drive->type != ATA_DISK) {
qd_write_reg(0x5f, QD_CONTROL_PORT);
outb(0x5f, QD_CONTROL_PORT);
printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO and post-write buffer on %s.\n", drive->name, drive->channel->name);
}
......@@ -299,8 +255,6 @@ static void qd6580_tune_drive(struct ata_device *drive, u8 pio)
}
/*
* qd_testreg
*
* tests if the given port is a register
*/
......@@ -329,8 +283,6 @@ static int __init qd_testreg(int port)
}
/*
* qd_setup:
*
* called to setup an ata channel : adjusts attributes & links for tuning
*/
......@@ -349,8 +301,6 @@ void __init qd_setup(int unit, int base, int config, unsigned int data0, unsigne
}
/*
* qd_unsetup:
*
* called to unsetup an ata channel : back to default values, unlinks tuning
*/
void __init qd_unsetup(int unit) {
......@@ -368,13 +318,13 @@ void __init qd_unsetup(int unit) {
if (tuneproc == (void *) qd6500_tune_drive) {
// will do it for both
qd_write_reg(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
outb(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
} else if (tuneproc == (void *) qd6580_tune_drive) {
if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
qd_write_reg(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
qd_write_reg(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
outb(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
outb(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
} else {
qd_write_reg(unit?QD6580_DEF_DATA2:QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
outb(unit ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
}
} else {
printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n");
......@@ -383,8 +333,6 @@ void __init qd_unsetup(int unit) {
}
/*
* qd_probe:
*
* looks at the specified baseport, and if qd found, registers & initialises it
* return 1 if another qd may be probed
*/
......@@ -394,7 +342,7 @@ int __init qd_probe(int base)
u8 config;
int unit;
config = qd_read_reg(QD_CONFIG_PORT);
config = inb(QD_CONFIG_PORT);
if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) return 1;
......@@ -425,7 +373,7 @@ int __init qd_probe(int base)
/* qd6580 found */
control = qd_read_reg(QD_CONTROL_PORT);
control = inb(QD_CONTROL_PORT);
printk(KERN_NOTICE "qd6580 at %#x\n", base);
printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n", config, control, QD_ID3);
......@@ -434,7 +382,7 @@ int __init qd_probe(int base)
/* secondary disabled */
printk(KERN_INFO "%s: qd6580: single IDE board\n", ide_hwifs[unit].name);
qd_setup(unit, base, config | (control << 8), QD6580_DEF_DATA, QD6580_DEF_DATA2, &qd6580_tune_drive);
qd_write_reg(QD_DEF_CONTR, QD_CONTROL_PORT);
outb(QD_DEF_CONTR, QD_CONTROL_PORT);
return 1;
} else {
......@@ -443,7 +391,7 @@ int __init qd_probe(int base)
qd_setup(ATA_PRIMARY, base, config | (control << 8), QD6580_DEF_DATA, QD6580_DEF_DATA, &qd6580_tune_drive);
qd_setup(ATA_SECONDARY, base, config | (control << 8), QD6580_DEF_DATA2, QD6580_DEF_DATA2, &qd6580_tune_drive);
qd_write_reg(QD_DEF_CONTR, QD_CONTROL_PORT);
outb(QD_DEF_CONTR, QD_CONTROL_PORT);
return 0; /* no other qd65xx possible */
}
......@@ -454,8 +402,6 @@ int __init qd_probe(int base)
#ifndef MODULE
/*
* init_qd65xx:
*
* called by ide.c when parsing command line
*/
......
/*
* Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
*/
/*
*
* Emulation of a SCSI host adapter for IDE ATAPI devices.
*
* With this driver, one can use the Linux SCSI drivers instead of the
* native IDE ATAPI drivers.
*
* Ver 0.1 Dec 3 96 Initial version.
* Ver 0.2 Jan 26 97 Fixed bug in cleanup_module() and added emulation
* of MODE_SENSE_6/MODE_SELECT_6 for cdroms. Thanks
* to Janos Farkas for pointing this out.
* Avoid using bitfields in structures for m68k.
* Added Scatter/Gather and DMA support.
* Ver 0.4 Dec 7 97 Add support for ATAPI PD/CD drives.
* Use variable timeout for each command.
* Ver 0.5 Jan 2 98 Fix previous PD/CD support.
* Allow disabling of SCSI-6 to SCSI-10 transformation.
* Ver 0.6 Jan 27 98 Allow disabling of SCSI command translation layer
* for access through /dev/sg.
* Fix MODE_SENSE_6/MODE_SELECT_6/INQUIRY translation.
* Ver 0.7 Dec 04 98 Ignore commands where lun != 0 to avoid multiple
* detection of devices with CONFIG_SCSI_MULTI_LUN
* Ver 0.8 Feb 05 99 Optical media need translation too. Reverse 0.7.
* Ver 0.9 Jul 04 99 Fix a bug in SG_SET_TRANSFORM.
*/
#define IDESCSI_VERSION "0.9"
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
......@@ -495,9 +474,8 @@ static void idescsi_release(struct inode *inode, struct file *filp, struct ata_d
static Scsi_Host_Template template;
static int idescsi_cleanup (struct ata_device *drive)
{
if (ide_unregister_subdriver (drive)) {
if (ata_unregister_device(drive))
return 1;
}
scsi_unregister_host(&template);
return 0;
......@@ -762,7 +740,7 @@ static void idescsi_attach(struct ata_device *drive)
host = scsi_register(&template, sizeof(idescsi_scsi_t));
if (!host) {
printk (KERN_ERR
printk(KERN_ERR
"ide-scsi: %s: Can't allocate a scsi host structure\n",
drive->name);
return;
......@@ -771,8 +749,8 @@ static void idescsi_attach(struct ata_device *drive)
host->max_lun = drive->last_lun + 1;
host->max_id = 1;
if (ide_register_subdriver(drive, &ata_ops)) {
printk (KERN_ERR "ide-scsi: %s: Failed to register the driver with ide.c\n", drive->name);
if (ata_register_device(drive, &ata_ops)) {
printk(KERN_ERR "ide-scsi: %s: Failed to register the driver with ide.c\n", drive->name);
scsi_unregister(host);
return;
}
......
......@@ -1146,23 +1146,23 @@ extern struct block_device_operations ide_fops[];
*/
extern int ideprobe_init(void);
#ifdef CONFIG_BLK_DEV_IDEDISK
extern int idedisk_init (void);
extern int idedisk_init(void);
#endif
#ifdef CONFIG_BLK_DEV_IDECD
extern int ide_cdrom_init (void);
extern int ide_cdrom_init(void);
#endif
#ifdef CONFIG_BLK_DEV_IDETAPE
extern int idetape_init (void);
extern int idetape_init(void);
#endif
#ifdef CONFIG_BLK_DEV_IDEFLOPPY
extern int idefloppy_init (void);
extern int idefloppy_init(void);
#endif
#ifdef CONFIG_BLK_DEV_IDESCSI
extern int idescsi_init (void);
extern int idescsi_init(void);
#endif
extern int ide_register_subdriver(struct ata_device *, struct ata_operations *);
extern int ide_unregister_subdriver(struct ata_device *drive);
extern int ata_register_device(struct ata_device *, struct ata_operations *);
extern int ata_unregister_device(struct ata_device *drive);
extern int ata_revalidate(kdev_t i_rdev);
extern void ide_driver_module(void);
......
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