Commit 916c2ff4 authored by Patrick Mochel's avatar Patrick Mochel

Merge bk://ldm@bkbits.net/linux-2.5-driverfs

into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-driverfs
parents f42ba7ce 9fb72010
......@@ -1337,6 +1337,12 @@ S: 998 East 900 South, Suite 26
S: Provo, Utah 84606-5607
S: USA
N: Marcel Holtmann
E: marcel@holtmann.org
W: http://www.holtmann.org
D: Author of the Linux Bluetooth Subsystem PC Card drivers
S: Germany
N: Rob W. W. Hooft
E: hooft@EMBL-Heidelberg.DE
D: Shared libs for graphics-tools and for the f2c compiler
......
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
......
......@@ -270,6 +270,12 @@ M: maxk@qualcomm.com
W: http://bluez.sf.net
S: Maintained
BLUETOOTH SUBSYSTEM (PC Card Drivers)
P: Marcel Holtmann
M: marcel@holtmann.org
W: http://www.holtmann.org/linux/bluetooth/
S: Maintained
BTTV VIDEO4LINUX DRIVER
P: Gerd Knorr
M: kraxel@bytesex.org
......
......@@ -62,6 +62,20 @@ CONFIG_BLUEZ_HCIDTL1
Say Y here to compile support for HCI DTL1 devices into the
kernel or say M to compile it as module (dtl1_cs.o).
HCI BT3C (PC Card) device driver
CONFIG_BLUEZ_HCIBT3C
Bluetooth HCI BT3C (PC Card) driver.
This driver provides support for Bluetooth PCMCIA devices with
3Com BT3C interface:
3Com Bluetooth Card (3CRWB6096)
HP Bluetooth Card
The HCI BT3C driver uses external firmware loader program provided in
the BlueFW package. For more information, see <http://bluez.sf.net>.
Say Y here to compile support for HCI BT3C devices into the
kernel or say M to compile it as module (bt3c_cs.o).
HCI BlueCard (PC Card) device driver
CONFIG_BLUEZ_HCIBLUECARD
Bluetooth HCI BlueCard (PC Card) driver.
......
......@@ -14,6 +14,8 @@ fi
dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
dep_tristate 'HCI BlueCard (PC Card) driver' CONFIG_BLUEZ_HCIBLUECARD $CONFIG_PCMCIA $CONFIG_BLUEZ
dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
......
......@@ -6,6 +6,7 @@ obj-$(CONFIG_BLUEZ_HCIUSB) += hci_usb.o
obj-$(CONFIG_BLUEZ_HCIVHCI) += hci_vhci.o
obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o
obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o
hci_uart-y := hci_ldisc.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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 */
}
/*
......
......@@ -218,6 +218,7 @@ static unsigned int __init pci_init_cs5530(struct pci_dev *dev)
}
}
}
if (!master_0) {
printk("%s: unable to locate PCI MASTER function\n", dev->name);
return 0;
......@@ -227,15 +228,13 @@ static unsigned int __init pci_init_cs5530(struct pci_dev *dev)
return 0;
}
save_flags(flags);
cli(); /* all CPUs (there should only be one CPU with this chipset) */
/*
* Enable BusMaster and MemoryWriteAndInvalidate for the cs5530:
* --> OR 0x14 into 16-bit PCI COMMAND reg of function 0 of the cs5530
*/
pci_read_config_word (cs5530_0, PCI_COMMAND, &pcicmd);
pci_write_config_word(cs5530_0, PCI_COMMAND, pcicmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
pci_set_master(cs5530_0);
pci_set_mwi(cs5530_0);
/*
* Set PCI CacheLineSize to 16-bytes:
......@@ -274,8 +273,6 @@ static unsigned int __init pci_init_cs5530(struct pci_dev *dev)
pci_write_config_byte(master_0, 0x42, 0x00);
pci_write_config_byte(master_0, 0x43, 0xc1);
restore_flags(flags);
return 0;
}
......
......@@ -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.. */
}
......
/*
* linux/drivers/ide/hd.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
*
* This is the low-level hd interrupt support. It traverses the
* request-list, using interrupts to jump between functions. As
* all the functions are called within interrupts, we may not
......@@ -37,7 +33,6 @@
#include <linux/fs.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/kernel.h>
#include <linux/hdreg.h>
#include <linux/genhd.h>
#include <linux/slab.h>
#include <linux/string.h>
......@@ -45,6 +40,7 @@
#include <linux/mc146818rtc.h> /* CMOS defines */
#include <linux/init.h>
#include <linux/blkpg.h>
#include <linux/hdreg.h>
#define REALLY_SLOW_IO
#include <asm/system.h>
......@@ -55,6 +51,15 @@
#define DEVICE_NR(device) (minor(device)>>6)
#include <linux/blk.h>
/* ATA commands we use.
*/
#define WIN_SPECIFY 0x91 /* set drive geometry translation */
#define WIN_RESTORE 0x10
#define WIN_READ 0x20 /* 28-Bit */
#define WIN_WRITE 0x30 /* 28-Bit */
#define HD_IRQ 14 /* the standard disk interrupt */
#ifdef __arm__
#undef HD_IRQ
#endif
......@@ -63,6 +68,45 @@
#define HD_IRQ IRQ_HARDDISK
#endif
/* Hd controller regster ports */
#define HD_DATA 0x1f0 /* _CTL when writing */
#define HD_ERROR 0x1f1 /* see err-bits */
#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */
#define HD_SECTOR 0x1f3 /* starting sector */
#define HD_LCYL 0x1f4 /* starting cylinder */
#define HD_HCYL 0x1f5 /* high byte of starting cyl */
#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */
#define HD_STATUS 0x1f7 /* see status-bits */
#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */
#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */
#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */
#define HD_CMD 0x3f6 /* used for resets */
#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */
/* Bits of HD_STATUS */
#define ERR_STAT 0x01
#define INDEX_STAT 0x02
#define ECC_STAT 0x04 /* Corrected error */
#define DRQ_STAT 0x08
#define SEEK_STAT 0x10
#define SERVICE_STAT SEEK_STAT
#define WRERR_STAT 0x20
#define READY_STAT 0x40
#define BUSY_STAT 0x80
/* Bits for HD_ERROR */
#define MARK_ERR 0x01 /* Bad address mark */
#define TRK0_ERR 0x02 /* couldn't find track 0 */
#define ABRT_ERR 0x04 /* Command aborted */
#define MCR_ERR 0x08 /* media change request */
#define ID_ERR 0x10 /* ID field not found */
#define MC_ERR 0x20 /* media changed */
#define ECC_ERR 0x40 /* Uncorrectable ECC error */
#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */
#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED;
static int revalidate_hddisk(kdev_t, int);
......@@ -162,12 +206,9 @@ void __init hd_setup(char *str, int *ints)
static void dump_status (const char *msg, unsigned int stat)
{
unsigned long flags;
char devc;
devc = !blk_queue_empty(QUEUE) ? 'a' + DEVICE_NR(CURRENT->rq_dev) : '?';
save_flags (flags);
sti();
#ifdef VERBOSE_ERRORS
printk("hd%c: %s: status=0x%02x { ", devc, msg, stat & 0xff);
if (stat & BUSY_STAT) printk("Busy ");
......@@ -207,8 +248,7 @@ static void dump_status (const char *msg, unsigned int stat)
hd_error = inb(HD_ERROR);
printk("hd%c: %s: error=0x%02x.\n", devc, msg, hd_error & 0xff);
}
#endif /* verbose errors */
restore_flags (flags);
#endif
}
void check_status(void)
......@@ -467,7 +507,7 @@ static void write_intr(void)
if (i > 0) {
SET_HANDLER(&write_intr);
outsw(HD_DATA,CURRENT->buffer,256);
sti();
local_irq_enable();
} else {
#if (HD_DELAY > 0)
last_req = read_timer();
......@@ -500,7 +540,7 @@ static void hd_times_out(unsigned long dummy)
return;
disable_irq(HD_IRQ);
sti();
local_irq_enable();
reset = 1;
dev = DEVICE_NR(CURRENT->rq_dev);
printk("hd%c: timeout\n", dev+'a');
......@@ -510,7 +550,7 @@ static void hd_times_out(unsigned long dummy)
#endif
end_request(CURRENT, 0);
}
cli();
local_irq_disable();
hd_request();
enable_irq(HD_IRQ);
}
......@@ -548,7 +588,7 @@ static void hd_request(void)
return;
repeat:
del_timer(&device_timer);
sti();
local_irq_enable();
if (blk_queue_empty(QUEUE)) {
do_hd = NULL;
......@@ -556,7 +596,7 @@ static void hd_request(void)
}
if (reset) {
cli();
local_irq_disable();
reset_hd();
return;
}
......@@ -688,7 +728,7 @@ static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (!handler)
handler = unexpected_hd_interrupt;
handler();
sti();
local_irq_enable();
}
static struct block_device_operations hd_fops = {
......
......@@ -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
......
......@@ -305,8 +305,9 @@
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/cdrom.h>
#include <linux/ide.h>
#include <linux/completion.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <asm/irq.h>
#include <asm/io.h>
......@@ -2914,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);
......@@ -2973,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;
}
......
......@@ -94,9 +94,10 @@
#include <linux/genhd.h>
#include <linux/slab.h>
#include <linux/cdrom.h>
#include <linux/buffer_head.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/atapi.h>
#include <linux/buffer_head.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
......@@ -1722,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;
}
......@@ -1779,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;
......
......@@ -550,7 +550,8 @@ static void __init hpt374_device_order_fixup (struct pci_dev *dev, struct ata_pc
if (!dev2) {
return;
} else {
byte irq = 0, irq2 = 0;
u8 irq = 0;
u8 irq2 = 0;
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
pci_read_config_byte(dev2, PCI_INTERRUPT_LINE, &irq2);
if (irq != irq2) {
......
This diff is collapsed.
......@@ -33,6 +33,15 @@
#include "ioctl.h"
/* BIG GEOMETRY - dying, used only by HDIO_GETGEO_BIG_RAW */
struct hd_big_geometry {
u8 heads;
u8 sectors;
u32 cylinders;
unsigned long start;
};
/*
* Implement generic ioctls invoked from userspace to imlpement specific
* functionality.
......
......@@ -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)
......
......@@ -191,7 +191,11 @@ static void init_hwif_data(struct ata_channel *ch, unsigned int index)
ch->noprobe = !ch->io_ports[IDE_DATA_OFFSET];
#ifdef CONFIG_BLK_DEV_HD
if (ch->io_ports[IDE_DATA_OFFSET] == HD_DATA)
/* Ignore disks for which handling by the legacy driver was requested
* by the used.
*/
if (ch->io_ports[IDE_DATA_OFFSET] == 0x1f0)
ch->noprobe = 1; /* may be overridden by ide_setup() */
#endif
......@@ -361,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;
......@@ -701,79 +705,46 @@ static void __init init_global_data(void)
/*
* 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.
* line" strings beginning with "hdx=". It gets called even before the actual
* module gets initialized.
*
* Please look at Documentation/ide.txt to see the complete list of supported
* options.
*/
int __init ide_setup(char *s)
static int __init ata_hd_setup(char *s)
{
int i, vals[4];
struct ata_channel *ch;
int vals[4];
struct ata_channel *ch; /* FIXME: Channel parms should not be accessed in ata_hd_setup */
struct ata_device *drive;
unsigned int hw, unit;
const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
const char max_ch = '0' + (MAX_HWIFS - 1);
if (!strncmp(s, "hd=", 3)) /* hd= is for hd.c driver and not us */
if (s[0] == '=') /* hd= is for hd.c driver and not us */
return 0;
if (strncmp(s,"ide",3) &&
strncmp(s,"hd",2)) /* hdx= & hdxlun= */
return 0;
printk(KERN_INFO "ide_setup: %s", s);
printk(KERN_INFO "hd%s", s);
init_global_data();
#ifdef CONFIG_BLK_DEV_IDEDOUBLER
if (!strcmp(s, "ide=doubler")) {
extern int ide_doubler;
printk(KERN_INFO" : Enabled support for IDE doublers\n");
ide_doubler = 1;
return 1;
}
#endif
if (!strcmp(s, "ide=nodma")) {
printk(KERN_INFO "ATA: Prevented DMA\n");
noautodma = 1;
return 1;
}
#ifdef CONFIG_PCI
if (!strcmp(s, "ide=reverse")) {
ide_scan_direction = 1;
printk(" : Enabled support for IDE inverse scan order.\n");
return 1;
}
#endif
/*
* Look for drive options: "hdx="
*/
if (!strncmp(s, "hd", 2) && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
if (s[0] >= 'a' && s[0] <= max_drive) {
static const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
"serialize", "autotune", "noautotune",
"slow", "flash", "remap", "noremap", "scsi", NULL};
unit = s[2] - 'a';
unit = s[0] - 'a';
hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES;
ch = &ide_hwifs[hw];
drive = &ch->drives[unit];
if (!strncmp(s+3, "=ide-", 5)) {
strncpy(drive->driver_req, s + 4, 9);
/* Look for hdx=ide-* */
if (!strncmp(s+1, "=ide-", 5)) {
strncpy(drive->driver_req, s+2, 9);
goto done;
}
/*
* Look for last lun option: "hdxlun="
*/
if (!strncmp(s+3, "lun=", 4)) {
if (*get_options(s+7, 2, vals) || vals[0]!=1)
if (!strncmp(s+1, "lun=", 4)) {
if (*get_options(s+5, 2, vals) || vals[0]!=1)
goto bad_option;
if (vals[1] >= 0 && vals[1] <= 7) {
drive->last_lun = vals[1];
......@@ -782,7 +753,7 @@ int __init ide_setup(char *s)
printk(" -- BAD LAST LUN! Expected value from 0 to 7");
goto done;
}
switch (match_parm(s+3, hd_words, vals, 3)) {
switch (match_parm(s+1, hd_words, vals, 3)) {
case -1: /* "none" */
drive->nobios = 1; /* drop into "noprobe" */
case -2: /* "noprobe" */
......@@ -790,16 +761,16 @@ int __init ide_setup(char *s)
goto done;
case -3: /* "nowerr" */
drive->bad_wstat = BAD_R_STAT;
ch->noprobe = 0;
ch->noprobe = 0; /* FIXME: Channel parm */
goto done;
case -4: /* "cdrom" */
drive->present = 1;
drive->type = ATA_ROM;
ch->noprobe = 0;
ch->noprobe = 0; /* FIXME: Channel parm */
goto done;
case -5: /* "serialize" */
printk(" -- USE \"ide%d=serialize\" INSTEAD", hw);
goto do_serialize;
goto bad_option;
case -6: /* "autotune" */
drive->autotune = 1;
goto done;
......@@ -807,7 +778,7 @@ int __init ide_setup(char *s)
drive->autotune = 2;
goto done;
case -8: /* "slow" */
ch->slow = 1;
ch->slow = 1; /* FIXME: Channel parm */
goto done;
case -9: /* "flash" */
drive->ata_flash = 1;
......@@ -840,11 +811,63 @@ int __init ide_setup(char *s)
}
}
bad_option:
printk(" -- BAD OPTION\n");
return 1;
done:
printk("\n");
return 1;
}
/*
* This gets called VERY EARLY during initialization, to handle kernel "command
* line" strings beginning with "ide". It gets called even before the actual
* module gets initialized.
*
* Please look at Documentation/ide.txt to see the complete list of supported
* options.
*/
int __init ide_setup(char *s)
{
int i, vals[4];
struct ata_channel *ch;
unsigned int hw;
const char max_ch = '0' + (MAX_HWIFS - 1);
printk(KERN_INFO "ide_setup: ide%s", s);
init_global_data();
#ifdef CONFIG_BLK_DEV_IDEDOUBLER
if (!strcmp(s, "=doubler")) {
extern int ide_doubler;
printk(KERN_INFO" : Enabled support for IDE doublers\n");
ide_doubler = 1;
return 1;
}
#endif
if (!strcmp(s, "=nodma")) {
printk(KERN_INFO "ATA: Prevented DMA\n");
noautodma = 1;
return 1;
}
#ifdef CONFIG_PCI
if (!strcmp(s, "=reverse")) {
ide_scan_direction = 1;
printk(" : Enabled support for IDE inverse scan order.\n");
return 1;
}
#endif
/*
* Look for bus speed option: "idebus="
*/
if (!strncmp(s, "idebus=", 7)) {
if (*get_options(s+7, 2, vals) || vals[0] != 1)
if (!strncmp(s, "bus=", 4)) {
if (*get_options(s+4, 2, vals) || vals[0] != 1)
goto bad_option;
idebus_parameter = vals[1];
goto done;
......@@ -853,7 +876,7 @@ int __init ide_setup(char *s)
/*
* Look for interface options: "idex="
*/
if (!strncmp(s, "ide", 3) && s[3] >= '0' && s[3] <= max_ch) {
if (s[0] >= '0' && s[0] <= max_ch) {
/*
* Be VERY CAREFUL changing this: note hardcoded indexes below
*/
......@@ -861,11 +884,11 @@ int __init ide_setup(char *s)
"noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66", NULL };
const char *ide_words[] = {
"qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
hw = s[3] - '0';
hw = s[0] - '0';
ch = &ide_hwifs[hw];
switch (match_parm(s+4, ide_options, vals, 1)) {
switch (match_parm(s+1, ide_options, vals, 1)) {
case -7: /* ata66 */
#ifdef CONFIG_PCI
ch->udma_four = 1;
......@@ -889,7 +912,6 @@ int __init ide_setup(char *s)
ch->drives[1].autotune = 1;
goto done;
case -2: /* "serialize" */
do_serialize:
{
struct ata_channel *mate;
......@@ -904,7 +926,10 @@ int __init ide_setup(char *s)
goto done;
}
i = match_parm(&s[4], ide_words, vals, 3);
/*
* Check for specific chipset name
*/
i = match_parm(s+1, ide_words, vals, 3);
/*
* Cryptic check to ensure chipset not already set for a channel:
......@@ -1012,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;
......@@ -1027,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;
......@@ -1046,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
......@@ -1078,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;
......@@ -1156,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);
......@@ -1432,9 +1448,15 @@ static int __init init_ata(void)
while ((options = next) != NULL) {
if ((next = strchr(options,' ')) != NULL)
*next++ = 0;
if (!ide_setup(options))
if (!strncmp(options,"hd",2)) {
if (!ata_hd_setup(options+2))
printk(KERN_ERR "Unknown option '%s'\n", options);
}
else if (!strncmp(options,"ide",3)) {
if (!ide_setup(options+3))
printk(KERN_ERR "Unknown option '%s'\n", options);
}
}
}
return ata_module_init();
}
......@@ -1457,6 +1479,7 @@ module_exit(cleanup_ata);
#ifndef MODULE
/* command line option parser */
__setup("", ide_setup);
__setup("ide", ide_setup);
__setup("hd", ata_hd_setup);
#endif
......@@ -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 */
}
/*
......
......@@ -1082,7 +1082,12 @@ static void channel_init(struct ata_channel *ch)
}
}
#ifdef CONFIG_BLK_DEV_HD
if (ch->irq == HD_IRQ && ch->io_ports[IDE_DATA_OFFSET] != HD_DATA) {
/* The first "legacy" HD gets distinguished by the IRQ it is attached
* to and the IO port it takes.
*/
if (ch->irq == 14 && ch->io_ports[IDE_DATA_OFFSET] != 0x1f0) {
printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", ch->name);
return;
......
/*
* 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
......@@ -86,31 +84,7 @@
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;
}
......
......@@ -40,43 +40,47 @@
static void pdump (void *, int);
#endif
/* Bits of HD_STATUS */
#define ERR_STAT 0x01
#define DRQ_STAT 0x08
struct freecom_udata {
__u8 buffer[64]; /* Common command block. */
u8 buffer[64]; /* Common command block. */
};
typedef struct freecom_udata *freecom_udata_t;
/* All of the outgoing packets are 64 bytes long. */
struct freecom_cb_wrap {
__u8 Type; /* Command type. */
__u8 Timeout; /* Timeout in seconds. */
__u8 Atapi[12]; /* An ATAPI packet. */
__u8 Filler[50]; /* Padding Data. */
u8 Type; /* Command type. */
u8 Timeout; /* Timeout in seconds. */
u8 Atapi[12]; /* An ATAPI packet. */
u8 Filler[50]; /* Padding Data. */
};
struct freecom_xfer_wrap {
__u8 Type; /* Command type. */
__u8 Timeout; /* Timeout in seconds. */
__u32 Count; /* Number of bytes to transfer. */
__u8 Pad[58];
u8 Type; /* Command type. */
u8 Timeout; /* Timeout in seconds. */
u32 Count; /* Number of bytes to transfer. */
u8 Pad[58];
} __attribute__ ((packed));
struct freecom_ide_out {
__u8 Type; /* Type + IDE register. */
__u8 Pad;
__u16 Value; /* Value to write. */
__u8 Pad2[60];
u8 Type; /* Type + IDE register. */
u8 Pad;
u16 Value; /* Value to write. */
u8 Pad2[60];
};
struct freecom_ide_in {
__u8 Type; /* Type | IDE register. */
__u8 Pad[63];
u8 Type; /* Type | IDE register. */
u8 Pad[63];
};
struct freecom_status {
__u8 Status;
__u8 Reason;
__u16 Count;
__u8 Pad[60];
u8 Status;
u8 Reason;
u16 Count;
u8 Pad[60];
};
/* Freecom stuffs the interrupt status in the INDEX_STAT bit of the ide
......
This diff is collapsed.
This diff is collapsed.
......@@ -608,22 +608,20 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
}
/*
* Ok, this is the main fork-routine. It copies the system process
* information (task[nr]) and sets up the necessary registers. It also
* copies the data segment in its entirety. The "stack_start" and
* "stack_top" arguments are simply passed along to the platform
* specific copy_thread() routine. Most platforms ignore stack_top.
* For an example that's using stack_top, see
* arch/ia64/kernel/process.c.
* This creates a new process as a copy of the old one,
* but does not actually start it yet.
*
* It copies the registers, and all the appropriate
* parts of the process environment (as per the clone
* flags). The actual kick-off is left to the caller.
*/
struct task_struct *do_fork(unsigned long clone_flags,
static struct task_struct *copy_process(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size)
{
int retval;
struct task_struct *p = NULL;
struct completion vfork;
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
return ERR_PTR(-EINVAL);
......@@ -680,10 +678,6 @@ struct task_struct *do_fork(unsigned long clone_flags,
INIT_LIST_HEAD(&p->sibling);
init_waitqueue_head(&p->wait_chldexit);
p->vfork_done = NULL;
if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
}
spin_lock_init(&p->alloc_lock);
spin_lock_init(&p->switch_lock);
......@@ -803,20 +797,6 @@ struct task_struct *do_fork(unsigned long clone_flags,
hash_pid(p);
nr_threads++;
write_unlock_irq(&tasklist_lock);
if (p->ptrace & PT_PTRACED)
send_sig(SIGSTOP, p, 1);
wake_up_forked_process(p); /* do this last */
++total_forks;
if (clone_flags & CLONE_VFORK)
wait_for_completion(&vfork);
else
/*
* Let the child process run first, to avoid most of the
* COW overhead when the child exec()s afterwards.
*/
set_need_resched();
retval = 0;
fork_out:
......@@ -850,6 +830,45 @@ struct task_struct *do_fork(unsigned long clone_flags,
goto fork_out;
}
/*
* Ok, this is the main fork-routine.
*
* It copies the process, and if successful kick-starts
* it and waits for it to finish using the VM if required.
*/
struct task_struct *do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size)
{
struct task_struct *p;
p = copy_process(clone_flags, stack_start, regs, stack_size);
if (!IS_ERR(p)) {
struct completion vfork;
if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
}
if (p->ptrace & PT_PTRACED)
send_sig(SIGSTOP, p, 1);
wake_up_forked_process(p); /* do this last */
++total_forks;
if (clone_flags & CLONE_VFORK)
wait_for_completion(&vfork);
else
/*
* Let the child process run first, to avoid most of the
* COW overhead when the child exec()s afterwards.
*/
set_need_resched();
}
return p;
}
/* SLAB cache for signal_struct structures (tsk->sig) */
kmem_cache_t *sigact_cachep;
......
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