Commit 1c01cb01 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/axboe/BK/linux-2.5-ide

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 5f6226d6 e75c5962
This diff is collapsed.
......@@ -7,22 +7,18 @@
# Note : at this point, these files are compiled on all systems.
# In the future, some of these should be built conditionally.
#
export-objs := ide-taskfile.o ide.o ide-probe.o ataraid.o
export-objs := device.o 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
obj-$(CONFIG_BLK_DEV_IDE) += ide-mod.o
obj-$(CONFIG_BLK_DEV_IDE) += ide-mod.o ide-probe-mod.o
obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o
obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o
obj-$(CONFIG_ATAPI) += atapi.o
obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy.o
obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o
obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
ide-obj-$(CONFIG_BLK_DEV_ADMA100) += adma100.o
ide-obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o
ide-obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
ide-obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o
......@@ -40,12 +36,12 @@ ide-obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
ide-obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o
ide-obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o
ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
ide-obj-$(CONFIG_BLK_DEV_IDEDMA) += quirks.o
ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI) += pcidma.o
ide-obj-$(CONFIG_BLK_DEV_IDE_TCQ) += tcq.o
ide-obj-$(CONFIG_PCI) += ide-pci.o
ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI) += ide-dma.o
ide-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ide-m8xx.o
ide-obj-$(CONFIG_BLK_DEV_IDEPCI) += ide-pci.o
ide-obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o
ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC) += ide-pmac.o
ide-obj-$(CONFIG_BLK_DEV_IDE_SWARM) += ide-swarm.o
ide-obj-$(CONFIG_BLK_DEV_MAC_IDE) += macide.o
ide-obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o
ide-obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o
......@@ -53,22 +49,19 @@ ide-obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o
ide-obj-$(CONFIG_BLK_DEV_PDC202XX) += pdc202xx.o
ide-obj-$(CONFIG_BLK_DEV_PDC4030) += pdc4030.o
ide-obj-$(CONFIG_BLK_DEV_PIIX) += piix.o
ide-obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
ide-obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o
ide-obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o
ide-obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o
ide-obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o
ide-obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o
ide-obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
ide-obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o
ide-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ide-m8xx.o
# The virtualised raid layers MUST come after the ide itself or bad stuff
# will happen.
obj-$(CONFIG_BLK_DEV_ATARAID) += ataraid.o
obj-$(CONFIG_BLK_DEV_ATARAID_PDC) += pdcraid.o
obj-$(CONFIG_BLK_DEV_ATARAID_HPT) += hptraid.o
ide-obj-$(CONFIG_PROC_FS) += ide-proc.o
ide-mod-objs := device.o ide-taskfile.o main.o ide.o probe.o \
ioctl.o ata-timing.o $(ide-obj-y)
ide-mod-objs := ide-taskfile.o ide.o $(ide-obj-y)
ide-probe-mod-objs := ide-probe.o ide-geometry.o
include $(TOPDIR)/Rules.make
/*
* linux/drivers/ide/adma100.c -- basic support for Pacific Digital ADMA-100 boards
*
* Created 09 Apr 2002 by Mark Lord
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
void __init ide_init_adma100 (ide_hwif_t *hwif)
{
u32 phy_admctl = pci_resource_start(hwif->pci_dev, 4) + 0x80 + (hwif->channel * 0x20);
void *v_admctl;
hwif->autodma = 0; // not compatible with normal IDE DMA transfers
hwif->dma_base = 0; // disable DMA completely
hwif->io_ports[IDE_CONTROL_OFFSET] += 4; // chip needs offset of 6 instead of 2
v_admctl = ioremap_nocache(phy_admctl, 1024); // map config regs, so we can turn on drive IRQs
*((unsigned short *)v_admctl) &= 3; // enable aIEN; preserve PIO mode
iounmap(v_admctl); // all done; unmap config regs
}
This diff is collapsed.
/*
* linux/drivers/ide/ali14xx.c Version 0.03 Feb 09, 1996
*
* Copyright (C) 1996 Linus Torvalds & author (see below)
*/
......@@ -13,7 +15,7 @@
* I think the code should be pretty understandable,
* but I'll be happy to (try to) answer questions.
*
* The critical part is in the ali14xx_tune_drive function. The init_registers
* The critical part is in the setupDrive function. The initRegisters
* function doesn't seem to be necessary, but the DOS driver does it, so
* I threw it in.
*
......@@ -35,27 +37,31 @@
* mode 4 for a while now with no trouble.) -Derek
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <asm/io.h>
#include "timing.h"
#include "ide_modes.h"
/* port addresses for auto-detection */
#define ALI_NUM_PORTS 4
static int ports[ALI_NUM_PORTS] __initdata =
{ 0x074, 0x0f4, 0x034, 0x0e4 };
static int ports[ALI_NUM_PORTS] __initdata = {0x074, 0x0f4, 0x034, 0x0e4};
/* register initialization data */
struct reg_initializer {
u8 reg, data;
};
typedef struct { byte reg, data; } RegInitializer;
static struct reg_initializer init_data[] __initdata = {
static RegInitializer initData[] __initdata = {
{0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00},
{0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f},
{0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00},
......@@ -65,164 +71,153 @@ static struct reg_initializer init_data[] __initdata = {
{0x35, 0x03}, {0x00, 0x00}
};
#define ALI_MAX_PIO 4
/* timing parameter registers for each drive */
static struct {
u8 reg1, reg2, reg3, reg4;
} reg_tab[4] = {
{
0x03, 0x26, 0x04, 0x27}, /* drive 0 */
{
0x05, 0x28, 0x06, 0x29}, /* drive 1 */
{
0x2b, 0x30, 0x2c, 0x31}, /* drive 2 */
{
0x2d, 0x32, 0x2e, 0x33}, /* drive 3 */
static struct { byte reg1, reg2, reg3, reg4; } regTab[4] = {
{0x03, 0x26, 0x04, 0x27}, /* drive 0 */
{0x05, 0x28, 0x06, 0x29}, /* drive 1 */
{0x2b, 0x30, 0x2c, 0x31}, /* drive 2 */
{0x2d, 0x32, 0x2e, 0x33}, /* drive 3 */
};
static int base_port; /* base port address */
static int reg_port; /* port for register number */
static int data_port; /* port for register data */
static u8 reg_on; /* output to base port to access registers */
static u8 reg_off; /* output to base port to close registers */
static int basePort; /* base port address */
static int regPort; /* port for register number */
static int dataPort; /* port for register data */
static byte regOn; /* output to base port to access registers */
static byte regOff; /* output to base port to close registers */
/*------------------------------------------------------------------------*/
/*
* Read a controller register.
*/
static inline u8 in_reg(u8 reg)
static inline byte inReg (byte reg)
{
outb_p(reg, reg_port);
return inb(data_port);
outb_p(reg, regPort);
return IN_BYTE(dataPort);
}
/*
* Write a controller register.
*/
static inline void out_reg(u8 data, u8 reg)
static void outReg (byte data, byte reg)
{
outb_p(reg, reg_port);
outb_p(data, data_port);
outb_p(reg, regPort);
outb_p(data, dataPort);
}
/*
* 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)
static void ali14xx_tune_drive (ide_drive_t *drive, byte pio)
{
int drive_num;
int driveNum;
int time1, time2;
u8 param1, param2, param3, param4;
struct ata_timing *t;
if (pio == 255)
pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO);
else
pio = XFER_PIO_0 + min_t(u8, pio, 4);
byte param1, param2, param3, param4;
unsigned long flags;
ide_pio_data_t d;
int bus_speed = system_bus_clock();
t = ata_timing_data(pio);
pio = ide_get_best_pio_mode(drive, pio, ALI_MAX_PIO, &d);
/* calculate timing, according to PIO mode */
time1 = t->cycle;
time2 = t->active;
param3 = param1 = (time2 * system_bus_speed + 999999) / 1000000;
param4 = param2 =
(time1 * system_bus_speed + 999999) / 1000000 - param1;
if (pio < XFER_PIO_3) {
time1 = d.cycle_time;
time2 = ide_pio_timings[pio].active_time;
param3 = param1 = (time2 * bus_speed + 999) / 1000;
param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1;
if (pio < 3) {
param3 += 8;
param4 += 8;
}
printk(KERN_DEBUG
"%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n",
drive->name, pio - XFER_PIO_0, time1, time2, param1, param2,
param3, param4);
printk("%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n",
drive->name, pio, time1, time2, param1, param2, param3, param4);
/* stuff timing parameters into controller registers */
drive_num = (drive->channel->index << 1) + drive->select.b.unit;
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);
driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit;
spin_lock_irqsave(&ide_lock, flags);
outb_p(regOn, basePort);
outReg(param1, regTab[driveNum].reg1);
outReg(param2, regTab[driveNum].reg2);
outReg(param3, regTab[driveNum].reg3);
outReg(param4, regTab[driveNum].reg4);
outb_p(regOff, basePort);
spin_unlock_irqrestore(&ide_lock, flags);
}
/*
* Auto-detect the IDE controller port.
*/
static int __init find_port(void)
static int __init findPort (void)
{
int i;
byte t;
unsigned long flags;
local_irq_save(flags);
for (i = 0; i < ALI_NUM_PORTS; i++) {
base_port = ports[i];
reg_off = inb(base_port);
for (reg_on = 0x30; reg_on <= 0x33; reg_on++) {
outb_p(reg_on, base_port);
if (inb(base_port) == reg_on) {
u8 t;
reg_port = base_port + 4;
data_port = base_port + 8;
t = in_reg(0) & 0xf0;
outb_p(reg_off, base_port);
for (i = 0; i < ALI_NUM_PORTS; ++i) {
basePort = ports[i];
regOff = IN_BYTE(basePort);
for (regOn = 0x30; regOn <= 0x33; ++regOn) {
outb_p(regOn, basePort);
if (IN_BYTE(basePort) == regOn) {
regPort = basePort + 4;
dataPort = basePort + 8;
t = inReg(0) & 0xf0;
outb_p(regOff, basePort);
local_irq_restore(flags);
if (t != 0x50)
return 0;
return 1; /* success */
}
}
outb_p(reg_off, base_port);
outb_p(regOff, basePort);
}
local_irq_restore(flags);
return 0;
}
/*
* Initialize controller registers with default values.
*/
static int __init init_registers(void)
{
struct reg_initializer *p;
static int __init initRegisters (void) {
RegInitializer *p;
byte t;
unsigned long flags;
u8 t;
local_irq_save(flags);
outb_p(reg_on, base_port);
for (p = init_data; p->reg != 0; ++p)
out_reg(p->data, p->reg);
outb_p(0x01, reg_port);
t = inb(reg_port) & 0x01;
outb_p(reg_off, base_port);
outb_p(regOn, basePort);
for (p = initData; p->reg != 0; ++p)
outReg(p->data, p->reg);
outb_p(0x01, regPort);
t = IN_BYTE(regPort) & 0x01;
outb_p(regOff, basePort);
local_irq_restore(flags);
return t;
}
void __init init_ali14xx(void)
void __init init_ali14xx (void)
{
/* auto-detect IDE controller port */
if (!find_port()) {
printk(KERN_ERR "ali14xx: not found\n");
if (!findPort()) {
printk("\nali14xx: not found");
return;
}
printk(KERN_DEBUG "ali14xx: base=%#03x, reg_on=%#02x\n",
base_port, reg_on);
printk("\nali14xx: base= 0x%03x, regOn = 0x%02x", basePort, regOn);
ide_hwifs[0].chipset = ide_ali14xx;
ide_hwifs[1].chipset = ide_ali14xx;
ide_hwifs[0].tuneproc = &ali14xx_tune_drive;
ide_hwifs[1].tuneproc = &ali14xx_tune_drive;
ide_hwifs[0].unit = ATA_PRIMARY;
ide_hwifs[1].unit = ATA_SECONDARY;
ide_hwifs[0].mate = &ide_hwifs[1];
ide_hwifs[1].mate = &ide_hwifs[0];
ide_hwifs[1].channel = 1;
/* initialize controller registers */
if (!init_registers()) {
printk(KERN_ERR "ali14xx: Chip initialization failed\n");
if (!initRegisters()) {
printk("\nali14xx: Chip initialization failed");
return;
}
}
This diff is collapsed.
This diff is collapsed.
/**** vi:set ts=8 sts=8 sw=8:************************************************
*
* Copyright (C) 2002 Marcin Dalecki <martin@dalecki.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
/*
* Code common among all the ATAPI device drivers.
*
* Ideally this should evolve in to a unified driver.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/cdrom.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/atapi.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
/*
* Initializes a packet command. Used by tape and floppy driver.
*/
void atapi_init_pc(struct atapi_packet_command *pc)
{
memset(pc->c, 0, 12);
pc->retries = 0;
pc->flags = 0;
pc->request_transfer = 0;
pc->buffer = pc->pc_buffer;
pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;
pc->b_data = NULL;
pc->bio = NULL;
}
/*
* Too bad. The drive wants to send us data which we are not ready to accept.
* Just throw it away.
*/
void atapi_discard_data(struct ata_device *drive, unsigned int bcount)
{
while (bcount--)
IN_BYTE(IDE_DATA_REG);
}
void atapi_write_zeros(struct ata_device *drive, unsigned int bcount)
{
while (bcount--)
OUT_BYTE(0, IDE_DATA_REG);
}
/*
* The following routines are mainly used by the ATAPI drivers.
*
* These routines will round up any request for an odd number of bytes, so if
* an odd n is specified, be sure that there's at least one extra byte
* allocated for the buffer.
*/
void atapi_read(struct ata_device *drive, u8 *buf, unsigned int n)
{
if (drive->channel->atapi_read) {
drive->channel->atapi_read(drive, buf, n);
return;
}
++n;
#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
if (MACH_IS_ATARI || MACH_IS_Q40) {
/* Atari has a byte-swapped IDE interface */
insw_swapw(IDE_DATA_REG, buf, n / 2);
return;
}
#endif
ata_read(drive, buf, n / 4);
if ((n & 0x03) >= 2)
insw(IDE_DATA_REG, buf + (n & ~0x03), 1);
}
void atapi_write(struct ata_device *drive, u8 *buf, unsigned int n)
{
if (drive->channel->atapi_write) {
drive->channel->atapi_write(drive, buf, n);
return;
}
++n;
#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
if (MACH_IS_ATARI || MACH_IS_Q40) {
/* Atari has a byte-swapped IDE interface */
outsw_swapw(IDE_DATA_REG, buf, n / 2);
return;
}
#endif
ata_write(drive, buf, n / 4);
if ((n & 0x03) >= 2)
outsw(IDE_DATA_REG, buf + (n & ~0x03), 1);
}
/*
* This function issues a special IDE device request onto the request queue.
*
* If action is ide_wait, then the rq is queued at the end of the request
* queue, and the function sleeps until it has been processed. This is for use
* when invoked from an ioctl handler.
*
* If action is ide_preempt, then the rq is queued at the head of the request
* queue, displacing the currently-being-processed request and this function
* returns immediately without waiting for the new rq to be completed. This is
* VERY DANGEROUS, and is intended for careful use by the ATAPI tape/cdrom
* driver code.
*
* If action is ide_end, then the rq is queued at the end of the request queue,
* and the function returns immediately without waiting for the new rq to be
* completed. This is again intended for careful use by the ATAPI tape/cdrom
* driver code.
*/
int ide_do_drive_cmd(struct ata_device *drive, struct request *rq, ide_action_t action)
{
unsigned long flags;
struct ata_channel *ch = drive->channel;
unsigned int major = ch->major;
request_queue_t *q = &drive->queue;
struct list_head *queue_head = &q->queue_head;
DECLARE_COMPLETION(wait);
#ifdef CONFIG_BLK_DEV_PDC4030
if (ch->chipset == ide_pdc4030 && rq->buffer)
return -ENOSYS; /* special drive cmds not supported */
#endif
rq->errors = 0;
rq->rq_status = RQ_ACTIVE;
rq->rq_dev = mk_kdev(major, (drive->select.b.unit) << PARTN_BITS);
if (action == ide_wait)
rq->waiting = &wait;
spin_lock_irqsave(ch->lock, flags);
if (action == ide_preempt)
drive->rq = NULL;
else if (!blk_queue_empty(&drive->queue))
queue_head = queue_head->prev; /* ide_end and ide_wait */
__elv_add_request(q, rq, queue_head);
do_ide_request(q);
spin_unlock_irqrestore(ch->lock, flags);
if (action == ide_wait) {
wait_for_completion(&wait); /* wait for it to be serviced */
return rq->errors ? -EIO : 0; /* return -EIO if errors */
}
return 0;
}
EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(atapi_discard_data);
EXPORT_SYMBOL(atapi_write_zeros);
EXPORT_SYMBOL(atapi_init_pc);
EXPORT_SYMBOL(atapi_read);
EXPORT_SYMBOL(atapi_write);
MODULE_LICENSE("GPL");
/*
ataraid.c Copyright (C) 2001 Red Hat, Inc. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
You should have received a copy of the GNU General Public License
(for example /usr/src/linux/COPYING); if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Authors: Arjan van de Ven <arjanv@redhat.com>
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/semaphore.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/genhd.h>
#include <linux/ioctl.h>
#include <linux/kdev_t.h>
#include <linux/swap.h>
#include <linux/buffer_head.h>
#include <linux/ide.h>
#include <asm/uaccess.h>
#include "ataraid.h"
static struct raid_device_operations *ataraid_ops[16];
static int ataraid_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
static int ataraid_open(struct inode *inode, struct file *filp);
static int ataraid_release(struct inode *inode, struct file *filp);
static void ataraid_split_request(request_queue_t * q, int rw,
struct buffer_head *bh);
static struct gendisk ataraid_gendisk[16];
static struct hd_struct *ataraid_part;
static char *ataraid_names;
static int ataraid_readahead[256];
static struct block_device_operations ataraid_fops = {
.owner = THIS_MODULE,
.open = ataraid_open,
.release = ataraid_release,
.ioctl = ataraid_ioctl,
};
static DECLARE_MUTEX(ataraid_sem);
/* Bitmap for the devices currently in use */
static unsigned int ataraiduse;
/* stub fops functions */
static int ataraid_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int minor;
minor = minor(inode->i_rdev) >> SHIFT;
if ((ataraid_ops[minor]) && (ataraid_ops[minor]->ioctl))
return (ataraid_ops[minor]->ioctl) (inode, file, cmd, arg);
return -EINVAL;
}
static int ataraid_open(struct inode *inode, struct file *filp)
{
int minor;
minor = minor(inode->i_rdev) >> SHIFT;
if ((ataraid_ops[minor]) && (ataraid_ops[minor]->open))
return (ataraid_ops[minor]->open) (inode, filp);
return -EINVAL;
}
static int ataraid_release(struct inode *inode, struct file *filp)
{
int minor;
minor = minor(inode->i_rdev) >> SHIFT;
if ((ataraid_ops[minor]) && (ataraid_ops[minor]->release))
return (ataraid_ops[minor]->release) (inode, filp);
return -EINVAL;
}
static int ataraid_make_request(request_queue_t * q, int rw,
struct buffer_head *bh)
{
int minor;
int retval;
minor = minor(bh->b_rdev) >> SHIFT;
if ((ataraid_ops[minor]) && (ataraid_ops[minor]->make_request)) {
retval = (ataraid_ops[minor]->make_request) (q, rw, bh);
if (retval == -1) {
ataraid_split_request(q, rw, bh);
return 0;
} else
return retval;
}
return -EINVAL;
}
struct buffer_head *ataraid_get_bhead(void)
{
void *ptr = NULL;
while (!ptr) {
ptr = kmalloc(sizeof(struct buffer_head), GFP_NOIO);
if (!ptr)
yield();
}
return ptr;
}
EXPORT_SYMBOL(ataraid_get_bhead);
struct ataraid_bh_private *ataraid_get_private(void)
{
void *ptr = NULL;
while (!ptr) {
ptr = kmalloc(sizeof(struct ataraid_bh_private), GFP_NOIO);
if (!ptr)
yield();
}
return ptr;
}
EXPORT_SYMBOL(ataraid_get_private);
void ataraid_end_request(struct buffer_head *bh, int uptodate)
{
struct ataraid_bh_private *private = bh->b_private;
if (private == NULL)
BUG();
if (atomic_dec_and_test(&private->count)) {
private->parent->b_end_io(private->parent, uptodate);
private->parent = NULL;
kfree(private);
}
kfree(bh);
}
EXPORT_SYMBOL(ataraid_end_request);
static void ataraid_split_request(request_queue_t * q, int rw,
struct buffer_head *bh)
{
struct buffer_head *bh1, *bh2;
struct ataraid_bh_private *private;
bh1 = ataraid_get_bhead();
bh2 = ataraid_get_bhead();
/* If either of those ever fails we're doomed */
if ((!bh1) || (!bh2))
BUG();
private = ataraid_get_private();
if (private == NULL)
BUG();
memcpy(bh1, bh, sizeof(*bh));
memcpy(bh2, bh, sizeof(*bh));
bh1->b_end_io = ataraid_end_request;
bh2->b_end_io = ataraid_end_request;
bh2->b_rsector += bh->b_size >> 10;
bh1->b_size /= 2;
bh2->b_size /= 2;
private->parent = bh;
bh1->b_private = private;
bh2->b_private = private;
atomic_set(&private->count, 2);
bh2->b_data += bh->b_size / 2;
generic_make_request(rw, bh1);
generic_make_request(rw, bh2);
}
/* device register / release functions */
int ataraid_get_device(struct raid_device_operations *fops)
{
int bit;
down(&ataraid_sem);
if (ataraiduse == ~0U) {
up(&ataraid_sem);
return -ENODEV;
}
bit = ffz(ataraiduse);
ataraiduse |= 1 << bit;
ataraid_ops[bit] = fops;
up(&ataraid_sem);
return bit;
}
void ataraid_release_device(int device)
{
down(&ataraid_sem);
if ((ataraiduse & (1 << device)) == 0)
BUG(); /* device wasn't registered at all */
ataraiduse &= ~(1 << device);
ataraid_ops[device] = NULL;
up(&ataraid_sem);
}
void ataraid_register_disk(int device, long size)
{
struct gendisk *disk = ataraid_gendisk + device;
char *name = ataraid_names + 12 * device;
sprintf(name, "ataraid/d%d", device);
disk->part = ataraid_part + 16 * device;
disk->major = ATAMAJOR;
disk->first_minor = 16 * device;
disk->major_name = name;
disk->minor_shift = 4;
disk->nr_real = 1;
disk->fops = &ataraid_fops;
add_gendisk(disk);
register_disk(disk,
mk_kdev(disk->major, disk->first_minor),
1 << disk->minor_shift,
disk->fops, size);
}
void ataraid_unregister_disk(int device)
{
del_gendisk(&ataraid_gendisk[device]);
}
static __init int ataraid_init(void)
{
int i;
for (i = 0; i < 256; i++)
ataraid_readahead[i] = 1023;
/* setup the gendisk structure */
ataraid_part = kmalloc(256 * sizeof(struct hd_struct), GFP_KERNEL);
ataraid_names = kmalloc(16 * 12, GFP_KERNEL);
if (!ataraid_part || !ataraid_names) {
kfree(ataraid_part);
kfree(ataraid_names);
printk(KERN_ERR
"ataraid: Couldn't allocate memory, aborting \n");
return -1;
}
memset(ataraid_part, 0, 256 * sizeof(struct hd_struct));
if (register_blkdev(ATAMAJOR, "ataraid", &ataraid_fops)) {
kfree(ataraid_part);
kfree(ataraid_names);
printk(KERN_ERR "ataraid: Could not get major %d \n",
ATAMAJOR);
return -1;
}
blk_queue_make_request(BLK_DEFAULT_QUEUE(ATAMAJOR),
ataraid_make_request);
return 0;
}
static void __exit ataraid_exit(void)
{
unregister_blkdev(ATAMAJOR, "ataraid");
kfree(ataraid_part);
kfree(ataraid_names);
}
module_init(ataraid_init);
module_exit(ataraid_exit);
EXPORT_SYMBOL(ataraid_get_device);
EXPORT_SYMBOL(ataraid_release_device);
EXPORT_SYMBOL(ataraid_register_disk);
EXPORT_SYMBOL(ataraid_unregister_disk);
MODULE_LICENSE("GPL");
/*
ataraid.h Copyright (C) 2001 Red Hat, Inc. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
You should have received a copy of the GNU General Public License
(for example /usr/src/linux/COPYING); if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Authors: Arjan van de Ven <arjanv@redhat.com>
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/semaphore.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/genhd.h>
#include <linux/ioctl.h>
#include <linux/ide.h>
#include <asm/uaccess.h>
#define ATAMAJOR 114
#define SHIFT 4
#define MINOR_MASK 15
#define MAJOR_MASK 15
/* raid_device_operations is a light struct block_device_operations with an
added method for make_request */
struct raid_device_operations {
int (*open) (struct inode *, struct file *);
int (*release) (struct inode *, struct file *);
int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
int (*make_request) (request_queue_t *q, int rw, struct buffer_head * bh);
};
struct geom {
unsigned char heads;
unsigned int cylinders;
unsigned char sectors;
};
/* structure for the splitting of bufferheads */
struct ataraid_bh_private {
struct buffer_head *parent;
atomic_t count;
};
extern int ataraid_get_device(struct raid_device_operations *fops);
extern void ataraid_release_device(int device);
extern void ataraid_register_disk(int device,long size);
extern void ataraid_unregister_disk(int device);
extern struct buffer_head *ataraid_get_bhead(void);
extern struct ataraid_bh_private *ataraid_get_private(void);
extern void ataraid_end_request(struct buffer_head *bh, int uptodate);
......@@ -117,7 +117,7 @@ typedef enum BuddhaType_Enum {
* Check and acknowledge the interrupt status
*/
static int buddha_ack_intr(struct ata_channel *hwif)
static int buddha_ack_intr(ide_hwif_t *hwif)
{
unsigned char ch;
......@@ -127,7 +127,7 @@ static int buddha_ack_intr(struct ata_channel *hwif)
return 1;
}
static int xsurf_ack_intr(struct ata_channel *hwif)
static int xsurf_ack_intr(ide_hwif_t *hwif)
{
unsigned char ch;
......@@ -204,7 +204,7 @@ void __init buddha_init(void)
xsurf_ack_intr, IRQ_AMIGA_PORTS);
}
index = ide_register_hw(&hw);
index = ide_register_hw(&hw, NULL);
if (index != -1) {
printk("ide%d: ", index);
switch(type) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* linux/drivers/ide/dtc2278.c Version 0.02 Feb 10, 1996
*
* Copyright (C) 1996 Linus Torvalds & author (see below)
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
......@@ -9,13 +13,13 @@
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/init.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <asm/io.h>
#include "timing.h"
#include "ide_modes.h"
/*
* Changing this #undef to #define may solve start up problems in some systems.
......@@ -53,31 +57,33 @@ static void sub22 (char b, char c)
int i;
for(i = 0; i < 3; ++i) {
inb(0x3f6);
IN_BYTE(0x3f6);
outb_p(b,0xb0);
inb(0x3f6);
IN_BYTE(0x3f6);
outb_p(c,0xb4);
inb(0x3f6);
if(inb(0xb4) == c) {
IN_BYTE(0x3f6);
if(IN_BYTE(0xb4) == c) {
outb_p(7,0xb0);
inb(0x3f6);
IN_BYTE(0x3f6);
return; /* success */
}
}
}
/* 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)
static void tune_dtc2278 (ide_drive_t *drive, byte pio)
{
pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
unsigned long flags;
pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
if (pio >= 3) {
spin_lock_irqsave(&ide_lock, flags);
/*
* This enables PIO mode4 (3?) on the first interface
*/
sub22(1,0xc3);
sub22(0,0xa0);
spin_unlock_irqrestore(&ide_lock, flags);
} else {
/* we don't know how to set it back again.. */
}
......@@ -85,7 +91,8 @@ static void tune_dtc2278(struct ata_device *drive, u8 pio)
/*
* 32bit I/O has to be enabled for *both* drives at the same time.
*/
drive->channel->io_32bit = 1;
drive->io_32bit = 1;
HWIF(drive)->drives[!drive->select.b.unit].io_32bit = 1;
}
void __init init_dtc2278 (void)
......@@ -97,9 +104,9 @@ void __init init_dtc2278 (void)
* This enables the second interface
*/
outb_p(4,0xb0);
inb(0x3f6);
IN_BYTE(0x3f6);
outb_p(0x20,0xb4);
inb(0x3f6);
IN_BYTE(0x3f6);
#ifdef ALWAYS_SET_DTC2278_PIO_MODE
/*
* This enables PIO mode4 (3?) on the first interface
......@@ -115,11 +122,11 @@ void __init init_dtc2278 (void)
ide_hwifs[0].chipset = ide_dtc2278;
ide_hwifs[1].chipset = ide_dtc2278;
ide_hwifs[0].tuneproc = &tune_dtc2278;
/* FIXME: What about the following?!
ide_hwifs[1].tuneproc = &tune_dtc2278;
*/
ide_hwifs[0].no_unmask = 1;
ide_hwifs[1].no_unmask = 1;
ide_hwifs[0].unit = ATA_PRIMARY;
ide_hwifs[1].unit = ATA_SECONDARY;
ide_hwifs[0].drives[0].no_unmask = 1;
ide_hwifs[0].drives[1].no_unmask = 1;
ide_hwifs[1].drives[0].no_unmask = 1;
ide_hwifs[1].drives[1].no_unmask = 1;
ide_hwifs[0].mate = &ide_hwifs[1];
ide_hwifs[1].mate = &ide_hwifs[0];
ide_hwifs[1].channel = 1;
}
......@@ -60,7 +60,7 @@ void __init falconide_init(void)
ide_setup_ports(&hw, (ide_ioreg_t)ATA_HD_BASE, falconide_offsets,
0, 0, NULL, IRQ_MFP_IDE);
index = ide_register_hw(&hw);
index = ide_register_hw(&hw, NULL);
if (index != -1)
printk("ide%d: Falcon IDE interface\n", index);
......
......@@ -16,6 +16,7 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/zorro.h>
#include <asm/setup.h>
#include <asm/amigahw.h>
......@@ -84,29 +85,29 @@ int ide_doubler = 0; /* support IDE doublers? */
* Check and acknowledge the interrupt status
*/
static int gayle_ack_intr_a4000(struct ata_channel *hwif)
static int gayle_ack_intr_a4000(ide_hwif_t *hwif)
{
unsigned char ch;
ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
if (!(ch & GAYLE_IRQ_IDE))
return 0;
return 1;
}
static int gayle_ack_intr_a1200(struct ata_channel *hwif)
static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
{
unsigned char ch;
ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
if (!(ch & GAYLE_IRQ_IDE))
return 0;
(void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
outb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
(void)z_readb(hwif->io_ports[IDE_STATUS_OFFSET]);
z_writeb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
return 1;
}
/*
/*
* Probe for a Gayle IDE interface (and optionally for an IDE doubler)
*/
......@@ -122,7 +123,7 @@ void __init gayle_init(void)
for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
ide_ioreg_t base, ctrlport, irqport;
int (*ack_intr)(struct ata_channel *);
ide_ack_intr_t *ack_intr;
hw_regs_t hw;
int index;
unsigned long phys_base, res_start, res_n;
......@@ -150,7 +151,7 @@ void __init gayle_init(void)
ide_setup_ports(&hw, base, gayle_offsets,
ctrlport, irqport, ack_intr, IRQ_AMIGA_PORTS);
index = ide_register_hw(&hw);
index = ide_register_hw(&hw, NULL);
if (index != -1) {
switch (i) {
case 0:
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* linux/drivers/ide/ide-adma.c Version 0.00 June 24, 2001
*
* Copyright (c) 2001 Andre Hedrick <andre@linux-ide.org>
*
* Asynchronous DMA -- TBA, this is a holding file.
*
*/
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/**** vi:set ts=8 sts=8 sw=8:************************************************
*
* Copyright (C) 2002 Marcin Dalecki <martin@dalecki.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
extern int ata_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -66,9 +66,12 @@ static int q40ide_default_irq(q40ide_ioreg_t base)
}
}
/*
/*
* Probe for Q40 IDE interfaces
*/
void q40ide_init(void)
{
int i;
......@@ -79,10 +82,10 @@ void q40ide_init(void)
for (i = 0; i < Q40IDE_NUM_HWIFS; i++) {
hw_regs_t hw;
ide_setup_ports(&hw, (ide_ioreg_t)pcide_bases[i], (int *)pcide_offsets,
(ide_ioreg_t)pcide_bases[i]+0x206,
ide_setup_ports(&hw,(ide_ioreg_t) pcide_bases[i], (int *)pcide_offsets,
pcide_bases[i]+0x206,
0, NULL, q40ide_default_irq(pcide_bases[i]));
ide_register_hw(&hw);
ide_register_hw(&hw, NULL);
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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