Commit 905adce4 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6: (23 commits)
  ide-acpi support warning fix
  ACPI support for IDE devices
  IDE Driver for Delkin/Lexar/etc.. cardbus CF adapter
  ide: it8213 IDE driver update (version 2)
  ide: add it8213 IDE driver
  tc86c001: add missing __init tag for tc86c001_ide_init()
  tc86c001: mark init_chipset_tc86c001() with __devinit tag
  tc86c001: init_hwif_tc86c001() can be static
  ide: add Toshiba TC86C001 IDE driver (take 2)
  pdc202xx_new: remove check_in_drive_lists abomination
  pdc202xx_new: remove useless code
  slc90e66: carry over fixes from piix driver
  piix: tuneproc() fixes/cleanups
  piix: fix 82371MX enablebits
  hpt366: HPT36x PCI clock detection fix
  hpt366: init code rewrite
  hpt366: clean up DMA timeout handling for HPT370
  hpt366: merge HPT37x speedproc handlers
  hpt366: cache channel's MCR address
  hpt366: switch to using pci_get_slot
  ...
parents 78149df6 1e8f34f7
......@@ -167,6 +167,13 @@ config BLK_DEV_IDECS
Support for Compact Flash cards, outboard IDE disks, tape drives,
and CD-ROM drives connected through a PCMCIA card.
config BLK_DEV_DELKIN
tristate "Cardbus IDE support (Delkin/ASKA/Workbit)"
depends on CARDBUS && PCI
help
Support for Delkin, ASKA, and Workbit Cardbus CompactFlash
Adapters. This may also work for similar SD and XD adapters.
config BLK_DEV_IDECD
tristate "Include IDE/ATAPI CDROM support"
---help---
......@@ -264,6 +271,13 @@ config BLK_DEV_IDESCSI
If both this SCSI emulation and native ATAPI support are compiled
into the kernel, the native support will be used.
config BLK_DEV_IDEACPI
bool "IDE ACPI support"
depends on ACPI
---help---
Implement ACPI support for generic IDE devices. On modern
machines ACPI support is required to properly handle ACPI S3 states.
config IDE_TASK_IOCTL
bool "IDE Taskfile Access"
help
......@@ -606,6 +620,11 @@ config BLK_DEV_PIIX
the kernel to change PIO, DMA and UDMA speeds and to configure
the chip to optimum performance.
config BLK_DEV_IT8213
tristate "IT8213 IDE support"
help
This driver adds support for the ITE 8213 IDE controller.
config BLK_DEV_IT821X
tristate "IT821X IDE support"
help
......@@ -742,6 +761,11 @@ config BLK_DEV_VIA82CXXX
This allows the kernel to change PIO, DMA and UDMA speeds and to
configure the chip to optimum performance.
config BLK_DEV_TC86C001
tristate "Toshiba TC86C001 support"
help
This driver adds support for Toshiba TC86C001 GOKU-S chip.
endif
config BLK_DEV_IDE_PMAC
......
......@@ -22,6 +22,7 @@ ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o
ide-core-$(CONFIG_PROC_FS) += ide-proc.o
ide-core-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o
# built-in only drivers from arm/
ide-core-$(CONFIG_IDE_ARM) += arm/ide_arm.o
......
/*
* ide-acpi.c
* Provides ACPI support for IDE drives.
*
* Copyright (C) 2005 Intel Corp.
* Copyright (C) 2005 Randy Dunlap
* Copyright (C) 2006 SUSE Linux Products GmbH
* Copyright (C) 2006 Hannes Reinecke
*/
#include <linux/ata.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <acpi/acpi.h>
#include <linux/ide.h>
#include <linux/pci.h>
#include <acpi/acpi_bus.h>
#include <acpi/acnames.h>
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
#include <acpi/acexcep.h>
#include <acpi/acmacros.h>
#include <acpi/actypes.h>
#define REGS_PER_GTF 7
struct taskfile_array {
u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
};
struct GTM_buffer {
u32 PIO_speed0;
u32 DMA_speed0;
u32 PIO_speed1;
u32 DMA_speed1;
u32 GTM_flags;
};
struct ide_acpi_drive_link {
ide_drive_t *drive;
acpi_handle obj_handle;
u8 idbuff[512];
};
struct ide_acpi_hwif_link {
ide_hwif_t *hwif;
acpi_handle obj_handle;
struct GTM_buffer gtm;
struct ide_acpi_drive_link master;
struct ide_acpi_drive_link slave;
};
#undef DEBUGGING
/* note: adds function name and KERN_DEBUG */
#ifdef DEBUGGING
#define DEBPRINT(fmt, args...) \
printk(KERN_DEBUG "%s: " fmt, __FUNCTION__, ## args)
#else
#define DEBPRINT(fmt, args...) do {} while (0)
#endif /* DEBUGGING */
extern int ide_noacpi;
extern int ide_noacpitfs;
extern int ide_noacpionboot;
/**
* ide_get_dev_handle - finds acpi_handle and PCI device.function
* @dev: device to locate
* @handle: returned acpi_handle for @dev
* @pcidevfn: return PCI device.func for @dev
*
* Returns the ACPI object handle to the corresponding PCI device.
*
* Returns 0 on success, <0 on error.
*/
static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
acpi_integer *pcidevfn)
{
struct pci_dev *pdev = to_pci_dev(dev);
unsigned int bus, devnum, func;
acpi_integer addr;
acpi_handle dev_handle;
struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
.pointer = NULL};
acpi_status status;
struct acpi_device_info *dinfo = NULL;
int ret = -ENODEV;
bus = pdev->bus->number;
devnum = PCI_SLOT(pdev->devfn);
func = PCI_FUNC(pdev->devfn);
/* ACPI _ADR encoding for PCI bus: */
addr = (acpi_integer)(devnum << 16 | func);
DEBPRINT("ENTER: pci %02x:%02x.%01x\n", bus, devnum, func);
dev_handle = DEVICE_ACPI_HANDLE(dev);
if (!dev_handle) {
DEBPRINT("no acpi handle for device\n");
goto err;
}
status = acpi_get_object_info(dev_handle, &buffer);
if (ACPI_FAILURE(status)) {
DEBPRINT("get_object_info for device failed\n");
goto err;
}
dinfo = buffer.pointer;
if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
dinfo->address == addr) {
*pcidevfn = addr;
*handle = dev_handle;
} else {
DEBPRINT("get_object_info for device has wrong "
" address: %llu, should be %u\n",
dinfo ? (unsigned long long)dinfo->address : -1ULL,
(unsigned int)addr);
goto err;
}
DEBPRINT("for dev=0x%x.%x, addr=0x%llx, *handle=0x%p\n",
devnum, func, (unsigned long long)addr, *handle);
ret = 0;
err:
kfree(dinfo);
return ret;
}
/**
* ide_acpi_hwif_get_handle - Get ACPI object handle for a given hwif
* @hwif: device to locate
*
* Retrieves the object handle for a given hwif.
*
* Returns handle on success, 0 on error.
*/
static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
{
struct device *dev = hwif->gendev.parent;
acpi_handle dev_handle;
acpi_integer pcidevfn;
acpi_handle chan_handle;
int err;
DEBPRINT("ENTER: device %s\n", hwif->name);
if (!dev) {
DEBPRINT("no PCI device for %s\n", hwif->name);
return NULL;
}
err = ide_get_dev_handle(dev, &dev_handle, &pcidevfn);
if (err < 0) {
DEBPRINT("ide_get_dev_handle failed (%d)\n", err);
return NULL;
}
/* get child objects of dev_handle == channel objects,
* + _their_ children == drive objects */
/* channel is hwif->channel */
chan_handle = acpi_get_child(dev_handle, hwif->channel);
DEBPRINT("chan adr=%d: handle=0x%p\n",
hwif->channel, chan_handle);
return chan_handle;
}
/**
* ide_acpi_drive_get_handle - Get ACPI object handle for a given drive
* @drive: device to locate
*
* Retrieves the object handle of a given drive. According to the ACPI
* spec the drive is a child of the hwif.
*
* Returns handle on success, 0 on error.
*/
static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
int port;
acpi_handle drive_handle;
if (!hwif->acpidata)
return NULL;
if (!hwif->acpidata->obj_handle)
return NULL;
port = hwif->channel ? drive->dn - 2: drive->dn;
DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
drive->name, hwif->channel, port);
/* TBD: could also check ACPI object VALID bits */
drive_handle = acpi_get_child(hwif->acpidata->obj_handle, port);
DEBPRINT("drive %s handle 0x%p\n", drive->name, drive_handle);
return drive_handle;
}
/**
* do_drive_get_GTF - get the drive bootup default taskfile settings
* @drive: the drive for which the taskfile settings should be retrieved
* @gtf_length: number of bytes of _GTF data returned at @gtf_address
* @gtf_address: buffer containing _GTF taskfile arrays
*
* The _GTF method has no input parameters.
* It returns a variable number of register set values (registers
* hex 1F1..1F7, taskfiles).
* The <variable number> is not known in advance, so have ACPI-CA
* allocate the buffer as needed and return it, then free it later.
*
* The returned @gtf_length and @gtf_address are only valid if the
* function return value is 0.
*/
static int do_drive_get_GTF(ide_drive_t *drive,
unsigned int *gtf_length, unsigned long *gtf_address,
unsigned long *obj_loc)
{
acpi_status status;
struct acpi_buffer output;
union acpi_object *out_obj;
ide_hwif_t *hwif = HWIF(drive);
struct device *dev = hwif->gendev.parent;
int err = -ENODEV;
int port;
*gtf_length = 0;
*gtf_address = 0UL;
*obj_loc = 0UL;
if (ide_noacpi)
return 0;
if (!dev) {
DEBPRINT("no PCI device for %s\n", hwif->name);
goto out;
}
if (!hwif->acpidata) {
DEBPRINT("no ACPI data for %s\n", hwif->name);
goto out;
}
port = hwif->channel ? drive->dn - 2: drive->dn;
if (!drive->acpidata) {
if (port == 0) {
drive->acpidata = &hwif->acpidata->master;
hwif->acpidata->master.drive = drive;
} else {
drive->acpidata = &hwif->acpidata->slave;
hwif->acpidata->slave.drive = drive;
}
}
DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
hwif->name, dev->bus_id, port, hwif->channel);
if (!drive->present) {
DEBPRINT("%s drive %d:%d not present\n",
hwif->name, hwif->channel, port);
goto out;
}
/* Get this drive's _ADR info. if not already known. */
if (!drive->acpidata->obj_handle) {
drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
if (!drive->acpidata->obj_handle) {
DEBPRINT("No ACPI object found for %s\n",
drive->name);
goto out;
}
}
/* Setting up output buffer */
output.length = ACPI_ALLOCATE_BUFFER;
output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
/* _GTF has no input parameters */
err = -EIO;
status = acpi_evaluate_object(drive->acpidata->obj_handle, "_GTF",
NULL, &output);
if (ACPI_FAILURE(status)) {
printk(KERN_DEBUG
"%s: Run _GTF error: status = 0x%x\n",
__FUNCTION__, status);
goto out;
}
if (!output.length || !output.pointer) {
DEBPRINT("Run _GTF: "
"length or ptr is NULL (0x%llx, 0x%p)\n",
(unsigned long long)output.length,
output.pointer);
goto out;
}
out_obj = output.pointer;
if (out_obj->type != ACPI_TYPE_BUFFER) {
DEBPRINT("Run _GTF: error: "
"expected object type of ACPI_TYPE_BUFFER, "
"got 0x%x\n", out_obj->type);
err = -ENOENT;
kfree(output.pointer);
goto out;
}
if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
out_obj->buffer.length % REGS_PER_GTF) {
printk(KERN_ERR
"%s: unexpected GTF length (%d) or addr (0x%p)\n",
__FUNCTION__, out_obj->buffer.length,
out_obj->buffer.pointer);
err = -ENOENT;
kfree(output.pointer);
goto out;
}
*gtf_length = out_obj->buffer.length;
*gtf_address = (unsigned long)out_obj->buffer.pointer;
*obj_loc = (unsigned long)out_obj;
DEBPRINT("returning gtf_length=%d, gtf_address=0x%lx, obj_loc=0x%lx\n",
*gtf_length, *gtf_address, *obj_loc);
err = 0;
out:
return err;
}
/**
* taskfile_load_raw - send taskfile registers to drive
* @drive: drive to which output is sent
* @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
*
* Outputs IDE taskfile to the drive.
*/
static int taskfile_load_raw(ide_drive_t *drive,
const struct taskfile_array *gtf)
{
ide_task_t args;
int err = 0;
DEBPRINT("(0x1f1-1f7): hex: "
"%02x %02x %02x %02x %02x %02x %02x\n",
gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
memset(&args, 0, sizeof(ide_task_t));
args.command_type = IDE_DRIVE_TASK_NO_DATA;
args.data_phase = TASKFILE_IN;
args.handler = &task_no_data_intr;
/* convert gtf to IDE Taskfile */
args.tfRegister[1] = gtf->tfa[0]; /* 0x1f1 */
args.tfRegister[2] = gtf->tfa[1]; /* 0x1f2 */
args.tfRegister[3] = gtf->tfa[2]; /* 0x1f3 */
args.tfRegister[4] = gtf->tfa[3]; /* 0x1f4 */
args.tfRegister[5] = gtf->tfa[4]; /* 0x1f5 */
args.tfRegister[6] = gtf->tfa[5]; /* 0x1f6 */
args.tfRegister[7] = gtf->tfa[6]; /* 0x1f7 */
if (ide_noacpitfs) {
DEBPRINT("_GTF execution disabled\n");
return err;
}
err = ide_raw_taskfile(drive, &args, NULL);
if (err)
printk(KERN_ERR "%s: ide_raw_taskfile failed: %u\n",
__FUNCTION__, err);
return err;
}
/**
* do_drive_set_taskfiles - write the drive taskfile settings from _GTF
* @drive: the drive to which the taskfile command should be sent
* @gtf_length: total number of bytes of _GTF taskfiles
* @gtf_address: location of _GTF taskfile arrays
*
* Write {gtf_address, length gtf_length} in groups of
* REGS_PER_GTF bytes.
*/
static int do_drive_set_taskfiles(ide_drive_t *drive,
unsigned int gtf_length,
unsigned long gtf_address)
{
int rc = -ENODEV, err;
int gtf_count = gtf_length / REGS_PER_GTF;
int ix;
struct taskfile_array *gtf;
if (ide_noacpi)
return 0;
DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn);
if (!drive->present)
goto out;
if (!gtf_count) /* shouldn't be here */
goto out;
DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n",
gtf_length, gtf_length, gtf_count, gtf_address);
if (gtf_length % REGS_PER_GTF) {
printk(KERN_ERR "%s: unexpected GTF length (%d)\n",
__FUNCTION__, gtf_length);
goto out;
}
rc = 0;
for (ix = 0; ix < gtf_count; ix++) {
gtf = (struct taskfile_array *)
(gtf_address + ix * REGS_PER_GTF);
/* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
err = taskfile_load_raw(drive, gtf);
if (err)
rc = err;
}
out:
return rc;
}
/**
* ide_acpi_exec_tfs - get then write drive taskfile settings
* @drive: the drive for which the taskfile settings should be
* written.
*
* According to the ACPI spec this should be called after _STM
* has been evaluated for the interface. Some ACPI vendors interpret
* that as a hard requirement and modify the taskfile according
* to the Identify Drive information passed down with _STM.
* So one should really make sure to call this only after _STM has
* been executed.
*/
int ide_acpi_exec_tfs(ide_drive_t *drive)
{
int ret;
unsigned int gtf_length;
unsigned long gtf_address;
unsigned long obj_loc;
if (ide_noacpi)
return 0;
DEBPRINT("call get_GTF, drive=%s port=%d\n", drive->name, drive->dn);
ret = do_drive_get_GTF(drive, &gtf_length, &gtf_address, &obj_loc);
if (ret < 0) {
DEBPRINT("get_GTF error (%d)\n", ret);
return ret;
}
DEBPRINT("call set_taskfiles, drive=%s\n", drive->name);
ret = do_drive_set_taskfiles(drive, gtf_length, gtf_address);
kfree((void *)obj_loc);
if (ret < 0) {
DEBPRINT("set_taskfiles error (%d)\n", ret);
}
DEBPRINT("ret=%d\n", ret);
return ret;
}
EXPORT_SYMBOL_GPL(ide_acpi_exec_tfs);
/**
* ide_acpi_get_timing - get the channel (controller) timings
* @hwif: target IDE interface (channel)
*
* This function executes the _GTM ACPI method for the target channel.
*
*/
void ide_acpi_get_timing(ide_hwif_t *hwif)
{
acpi_status status;
struct acpi_buffer output;
union acpi_object *out_obj;
if (ide_noacpi)
return;
DEBPRINT("ENTER:\n");
if (!hwif->acpidata) {
DEBPRINT("no ACPI data for %s\n", hwif->name);
return;
}
/* Setting up output buffer for _GTM */
output.length = ACPI_ALLOCATE_BUFFER;
output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
/* _GTM has no input parameters */
status = acpi_evaluate_object(hwif->acpidata->obj_handle, "_GTM",
NULL, &output);
DEBPRINT("_GTM status: %d, outptr: 0x%p, outlen: 0x%llx\n",
status, output.pointer,
(unsigned long long)output.length);
if (ACPI_FAILURE(status)) {
DEBPRINT("Run _GTM error: status = 0x%x\n", status);
return;
}
if (!output.length || !output.pointer) {
DEBPRINT("Run _GTM: length or ptr is NULL (0x%llx, 0x%p)\n",
(unsigned long long)output.length,
output.pointer);
kfree(output.pointer);
return;
}
out_obj = output.pointer;
if (out_obj->type != ACPI_TYPE_BUFFER) {
kfree(output.pointer);
DEBPRINT("Run _GTM: error: "
"expected object type of ACPI_TYPE_BUFFER, "
"got 0x%x\n", out_obj->type);
return;
}
if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
out_obj->buffer.length != sizeof(struct GTM_buffer)) {
kfree(output.pointer);
printk(KERN_ERR
"%s: unexpected _GTM length (0x%x)[should be 0x%zx] or "
"addr (0x%p)\n",
__FUNCTION__, out_obj->buffer.length,
sizeof(struct GTM_buffer), out_obj->buffer.pointer);
return;
}
memcpy(&hwif->acpidata->gtm, out_obj->buffer.pointer,
sizeof(struct GTM_buffer));
DEBPRINT("_GTM info: ptr: 0x%p, len: 0x%x, exp.len: 0x%Zx\n",
out_obj->buffer.pointer, out_obj->buffer.length,
sizeof(struct GTM_buffer));
DEBPRINT("_GTM fields: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
hwif->acpidata->gtm.PIO_speed0,
hwif->acpidata->gtm.DMA_speed0,
hwif->acpidata->gtm.PIO_speed1,
hwif->acpidata->gtm.DMA_speed1,
hwif->acpidata->gtm.GTM_flags);
kfree(output.pointer);
}
EXPORT_SYMBOL_GPL(ide_acpi_get_timing);
/**
* ide_acpi_push_timing - set the channel (controller) timings
* @hwif: target IDE interface (channel)
*
* This function executes the _STM ACPI method for the target channel.
*
* _STM requires Identify Drive data, which has to passed as an argument.
* Unfortunately hd_driveid is a mangled version which we can't readily
* use; hence we'll get the information afresh.
*/
void ide_acpi_push_timing(ide_hwif_t *hwif)
{
acpi_status status;
struct acpi_object_list input;
union acpi_object in_params[3];
struct ide_acpi_drive_link *master = &hwif->acpidata->master;
struct ide_acpi_drive_link *slave = &hwif->acpidata->slave;
if (ide_noacpi)
return;
DEBPRINT("ENTER:\n");
if (!hwif->acpidata) {
DEBPRINT("no ACPI data for %s\n", hwif->name);
return;
}
/* Give the GTM buffer + drive Identify data to the channel via the
* _STM method: */
/* setup input parameters buffer for _STM */
input.count = 3;
input.pointer = in_params;
in_params[0].type = ACPI_TYPE_BUFFER;
in_params[0].buffer.length = sizeof(struct GTM_buffer);
in_params[0].buffer.pointer = (u8 *)&hwif->acpidata->gtm;
in_params[1].type = ACPI_TYPE_BUFFER;
in_params[1].buffer.length = sizeof(struct hd_driveid);
in_params[1].buffer.pointer = (u8 *)&master->idbuff;
in_params[2].type = ACPI_TYPE_BUFFER;
in_params[2].buffer.length = sizeof(struct hd_driveid);
in_params[2].buffer.pointer = (u8 *)&slave->idbuff;
/* Output buffer: _STM has no output */
status = acpi_evaluate_object(hwif->acpidata->obj_handle, "_STM",
&input, NULL);
if (ACPI_FAILURE(status)) {
DEBPRINT("Run _STM error: status = 0x%x\n", status);
}
DEBPRINT("_STM status: %d\n", status);
}
EXPORT_SYMBOL_GPL(ide_acpi_push_timing);
/**
* ide_acpi_init - initialize the ACPI link for an IDE interface
* @hwif: target IDE interface (channel)
*
* The ACPI spec is not quite clear when the drive identify buffer
* should be obtained. Calling IDENTIFY DEVICE during shutdown
* is not the best of ideas as the drive might already being put to
* sleep. And obviously we can't call it during resume.
* So we get the information during startup; but this means that
* any changes during run-time will be lost after resume.
*/
void ide_acpi_init(ide_hwif_t *hwif)
{
int unit;
int err;
struct ide_acpi_drive_link *master;
struct ide_acpi_drive_link *slave;
hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL);
if (!hwif->acpidata)
return;
hwif->acpidata->obj_handle = ide_acpi_hwif_get_handle(hwif);
if (!hwif->acpidata->obj_handle) {
DEBPRINT("no ACPI object for %s found\n", hwif->name);
kfree(hwif->acpidata);
hwif->acpidata = NULL;
return;
}
/*
* The ACPI spec mandates that we send information
* for both drives, regardless whether they are connected
* or not.
*/
hwif->acpidata->master.drive = &hwif->drives[0];
hwif->drives[0].acpidata = &hwif->acpidata->master;
master = &hwif->acpidata->master;
hwif->acpidata->slave.drive = &hwif->drives[1];
hwif->drives[1].acpidata = &hwif->acpidata->slave;
slave = &hwif->acpidata->slave;
/*
* Send IDENTIFY for each drive
*/
if (master->drive->present) {
err = taskfile_lib_get_identify(master->drive, master->idbuff);
if (err) {
DEBPRINT("identify device %s failed (%d)\n",
master->drive->name, err);
}
}
if (slave->drive->present) {
err = taskfile_lib_get_identify(slave->drive, slave->idbuff);
if (err) {
DEBPRINT("identify device %s failed (%d)\n",
slave->drive->name, err);
}
}
if (ide_noacpionboot) {
DEBPRINT("ACPI methods disabled on boot\n");
return;
}
/*
* ACPI requires us to call _STM on startup
*/
ide_acpi_get_timing(hwif);
ide_acpi_push_timing(hwif);
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
if (drive->present) {
/* Execute ACPI startup code */
ide_acpi_exec_tfs(drive);
}
}
}
EXPORT_SYMBOL_GPL(ide_acpi_init);
......@@ -1384,6 +1384,9 @@ static int hwif_init(ide_hwif_t *hwif)
done:
init_gendisk(hwif);
ide_acpi_init(hwif);
hwif->present = 1; /* success */
return 1;
......
......@@ -187,6 +187,12 @@ int noautodma = 1;
EXPORT_SYMBOL(noautodma);
#ifdef CONFIG_BLK_DEV_IDEACPI
int ide_noacpi = 0;
int ide_noacpitfs = 1;
int ide_noacpionboot = 1;
#endif
/*
* This is declared extern in ide.h, for access by other IDE modules:
*/
......@@ -1214,10 +1220,15 @@ EXPORT_SYMBOL(system_bus_clock);
static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
{
ide_drive_t *drive = dev->driver_data;
ide_hwif_t *hwif = HWIF(drive);
struct request rq;
struct request_pm_state rqpm;
ide_task_t args;
/* Call ACPI _GTM only once */
if (!(drive->dn % 2))
ide_acpi_get_timing(hwif);
memset(&rq, 0, sizeof(rq));
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
......@@ -1235,10 +1246,17 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg)
static int generic_ide_resume(struct device *dev)
{
ide_drive_t *drive = dev->driver_data;
ide_hwif_t *hwif = HWIF(drive);
struct request rq;
struct request_pm_state rqpm;
ide_task_t args;
/* Call ACPI _STM only once */
if (!(drive->dn % 2))
ide_acpi_push_timing(hwif);
ide_acpi_exec_tfs(drive);
memset(&rq, 0, sizeof(rq));
memset(&rqpm, 0, sizeof(rqpm));
memset(&args, 0, sizeof(args));
......@@ -1543,6 +1561,24 @@ static int __init ide_setup(char *s)
}
#endif /* CONFIG_BLK_DEV_IDEPCI */
#ifdef CONFIG_BLK_DEV_IDEACPI
if (!strcmp(s, "ide=noacpi")) {
//printk(" : Disable IDE ACPI support.\n");
ide_noacpi = 1;
return 1;
}
if (!strcmp(s, "ide=acpigtf")) {
//printk(" : Enable IDE ACPI _GTF support.\n");
ide_noacpitfs = 0;
return 1;
}
if (!strcmp(s, "ide=acpionboot")) {
//printk(" : Call IDE ACPI methods on boot.\n");
ide_noacpionboot = 0;
return 1;
}
#endif /* CONFIG_BLK_DEV_IDEACPI */
/*
* Look for drive options: "hdx="
*/
......
......@@ -9,9 +9,10 @@ obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o
obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o
#obj-$(CONFIG_BLK_DEV_HPT37X) += hpt37x.o
obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o
obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o
obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o
obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o
......@@ -26,6 +27,7 @@ obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o
obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o
obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o
obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o
obj-$(CONFIG_BLK_DEV_TC86C001) += tc86c001.o
obj-$(CONFIG_BLK_DEV_TRIFLEX) += triflex.o
obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o
obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o
......
/*
* linux/drivers/ide/pci/delkin_cb.c
*
* Created 20 Oct 2004 by Mark Lord
*
* Basic support for Delkin/ASKA/Workbit Cardbus CompactFlash adapter
*
* Modeled after the 16-bit PCMCIA driver: ide-cs.c
*
* This is slightly peculiar, in that it is a PCI driver,
* but is NOT an IDE PCI driver -- the IDE layer does not directly
* support hot insertion/removal of PCI interfaces, so this driver
* is unable to use the IDE PCI interfaces. Instead, it uses the
* same interfaces as the ide-cs (PCMCIA) driver uses.
* On the plus side, the driver is also smaller/simpler this way.
*
* 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/autoconf.h>
#include <linux/types.h>
#include <linux/module.h>
#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>
/*
* No chip documentation has yet been found,
* so these configuration values were pulled from
* a running Win98 system using "debug".
* This gives around 3MByte/second read performance,
* which is about 2/3 of what the chip is capable of.
*
* There is also a 4KByte mmio region on the card,
* but its purpose has yet to be reverse-engineered.
*/
static const u8 setup[] = {
0x00, 0x05, 0xbe, 0x01, 0x20, 0x8f, 0x00, 0x00,
0xa4, 0x1f, 0xb3, 0x1b, 0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xa4, 0x83, 0x02, 0x13,
};
static int __devinit
delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
unsigned long base;
hw_regs_t hw;
ide_hwif_t *hwif = NULL;
ide_drive_t *drive;
int i, rc;
rc = pci_enable_device(dev);
if (rc) {
printk(KERN_ERR "delkin_cb: pci_enable_device failed (%d)\n", rc);
return rc;
}
rc = pci_request_regions(dev, "delkin_cb");
if (rc) {
printk(KERN_ERR "delkin_cb: pci_request_regions failed (%d)\n", rc);
pci_disable_device(dev);
return rc;
}
base = pci_resource_start(dev, 0);
outb(0x02, base + 0x1e); /* set nIEN to block interrupts */
inb(base + 0x17); /* read status to clear interrupts */
for (i = 0; i < sizeof(setup); ++i) {
if (setup[i])
outb(setup[i], base + i);
}
pci_release_regions(dev); /* IDE layer handles regions itself */
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base + 0x10, base + 0x1e);
hw.irq = dev->irq;
hw.chipset = ide_pci; /* this enables IRQ sharing */
rc = ide_register_hw_with_fixup(&hw, &hwif, ide_undecoded_slave);
if (rc < 0) {
printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
pci_disable_device(dev);
return -ENODEV;
}
pci_set_drvdata(dev, hwif);
hwif->pci_dev = dev;
drive = &hwif->drives[0];
if (drive->present) {
drive->io_32bit = 1;
drive->unmask = 1;
}
return 0;
}
static void
delkin_cb_remove (struct pci_dev *dev)
{
ide_hwif_t *hwif = pci_get_drvdata(dev);
if (hwif)
ide_unregister(hwif->index);
pci_disable_device(dev);
}
static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = {
{ 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, delkin_cb_pci_tbl);
static struct pci_driver driver = {
.name = "Delkin-ASKA-Workbit Cardbus IDE",
.id_table = delkin_cb_pci_tbl,
.probe = delkin_cb_probe,
.remove = delkin_cb_remove,
};
static int
delkin_cb_init (void)
{
return pci_module_init(&driver);
}
static void
delkin_cb_exit (void)
{
pci_unregister_driver(&driver);
}
module_init(delkin_cb_init);
module_exit(delkin_cb_exit);
MODULE_AUTHOR("Mark Lord");
MODULE_DESCRIPTION("Basic support for Delkin/ASKA/Workbit Cardbus IDE");
MODULE_LICENSE("GPL");
/*
* linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003
* linux/drivers/ide/pci/hpt366.c Version 1.01 Dec 23, 2006
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
......@@ -60,13 +60,10 @@
* channel caused the cached register value to get out of sync with the
* actual one, the channels weren't serialized, the turnaround shouldn't
* be done on 66 MHz PCI bus
* - avoid calibrating PLL twice as the second time results in a wrong PCI
* frequency and thus in the wrong timings for the secondary channel
* - disable UltraATA/133 for HPT372 by default (50 MHz DPLL clock do not
* allow for this speed anyway)
* - add support for HPT302N and HPT371N clocking (the same as for HPT372N)
* - HPT371/N are single channel chips, so avoid touching the primary channel
* which exists only virtually (there's no pins for it)
* - disable UltraATA/100 for HPT370 by default as the 33 MHz clock being used
* does not allow for this speed anyway
* - avoid touching disabled channels (e.g. HPT371/N are single channel chips,
* their primary channel is kind of virtual, it isn't tied to any pins)
* - fix/remove bad/unused timing tables and use one set of tables for the whole
* HPT37x chip family; save space by introducing the separate transfer mode
* table in which the mode lookup is done
......@@ -76,11 +73,47 @@
* and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead
* - pass to init_chipset() handlers a copy of the IDE PCI device structure as
* they tamper with its fields
* <source@mvista.com>
*
* - pass to the init_setup handlers a copy of the ide_pci_device_t structure
* since they may tamper with its fields
* - prefix the driver startup messages with the real chip name
* - claim the extra 240 bytes of I/O space for all chips
* - optimize the rate masking/filtering and the drive list lookup code
* - use pci_get_slot() to get to the function 1 of HPT36x/374
* - cache offset of the channel's misc. control registers (MCRs) being used
* throughout the driver
* - only touch the relevant MCR when detecting the cable type on HPT374's
* function 1
* - rename all the register related variables consistently
* - move all the interrupt twiddling code from the speedproc handlers into
* init_hwif_hpt366(), also grouping all the DMA related code together there
* - merge two HPT37x speedproc handlers, fix the PIO timing register mask and
* separate the UltraDMA and MWDMA masks there to avoid changing PIO timings
* when setting an UltraDMA mode
* - fix hpt3xx_tune_drive() to set the PIO mode requested, not always select
* the best possible one
* - clean up DMA timeout handling for HPT370
* - switch to using the enumeration type to differ between the numerous chip
* variants, matching PCI device/revision ID with the chip type early, at the
* init_setup stage
* - extend the hpt_info structure to hold the DPLL and PCI clock frequencies,
* stop duplicating it for each channel by storing the pointer in the pci_dev
* structure: first, at the init_setup stage, point it to a static "template"
* with only the chip type and its specific base DPLL frequency, the highest
* supported DMA mode, and the chip settings table pointer filled, then, at
* the init_chipset stage, allocate per-chip instance and fill it with the
* rest of the necessary information
* - get rid of the constant thresholds in the HPT37x PCI clock detection code,
* switch to calculating PCI clock frequency based on the chip's base DPLL
* frequency
* - switch to using the DPLL clock and enable UltraATA/133 mode by default on
* anything newer than HPT370/A
* - fold PCI clock detection and DPLL setup code into init_chipset_hpt366(),
* also fixing the interchanged 25/40 MHz PCI clock cases for HPT36x chips;
* unify HPT36x/37x timing setup code and the speedproc handlers by joining
* the register setting lists into the table indexed by the clock selected
* Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com>
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
......@@ -332,93 +365,159 @@ static u32 sixty_six_base_hpt37x[] = {
};
#define HPT366_DEBUG_DRIVE_INFO 0
#define HPT374_ALLOW_ATA133_6 0
#define HPT371_ALLOW_ATA133_6 0
#define HPT302_ALLOW_ATA133_6 0
#define HPT372_ALLOW_ATA133_6 0
#define HPT370_ALLOW_ATA100_5 1
#define HPT374_ALLOW_ATA133_6 1
#define HPT371_ALLOW_ATA133_6 1
#define HPT302_ALLOW_ATA133_6 1
#define HPT372_ALLOW_ATA133_6 1
#define HPT370_ALLOW_ATA100_5 0
#define HPT366_ALLOW_ATA66_4 1
#define HPT366_ALLOW_ATA66_3 1
#define HPT366_MAX_DEVS 8
#define F_LOW_PCI_33 0x23
#define F_LOW_PCI_40 0x29
#define F_LOW_PCI_50 0x2d
#define F_LOW_PCI_66 0x42
/* Supported ATA clock frequencies */
enum ata_clock {
ATA_CLOCK_25MHZ,
ATA_CLOCK_33MHZ,
ATA_CLOCK_40MHZ,
ATA_CLOCK_50MHZ,
ATA_CLOCK_66MHZ,
NUM_ATA_CLOCKS
};
/*
* Hold all the highpoint quirks and revision information in one
* place.
* Hold all the HighPoint chip information in one place.
*/
struct hpt_info
{
struct hpt_info {
u8 chip_type; /* Chip type */
u8 max_mode; /* Speeds allowed */
int revision; /* Chipset revision */
int flags; /* Chipset properties */
#define PLL_MODE 1
#define IS_3xxN 2
#define PCI_66MHZ 4
/* Speed table */
u32 *speed;
u8 dpll_clk; /* DPLL clock in MHz */
u8 pci_clk; /* PCI clock in MHz */
u32 **settings; /* Chipset settings table */
};
/*
* This wants fixing so that we do everything not by classrev
* (which breaks on the newest chips) but by creating an
* enumeration of chip variants and using that
*/
/* Supported HighPoint chips */
enum {
HPT36x,
HPT370,
HPT370A,
HPT374,
HPT372,
HPT372A,
HPT302,
HPT371,
HPT372N,
HPT302N,
HPT371N
};
static u32 *hpt36x_settings[NUM_ATA_CLOCKS] = {
twenty_five_base_hpt36x,
thirty_three_base_hpt36x,
forty_base_hpt36x,
NULL,
NULL
};
static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = {
NULL,
thirty_three_base_hpt37x,
NULL,
fifty_base_hpt37x,
sixty_six_base_hpt37x
};
static struct hpt_info hpt36x __devinitdata = {
.chip_type = HPT36x,
.max_mode = (HPT366_ALLOW_ATA66_4 || HPT366_ALLOW_ATA66_3) ? 2 : 1,
.dpll_clk = 0, /* no DPLL */
.settings = hpt36x_settings
};
static struct hpt_info hpt370 __devinitdata = {
.chip_type = HPT370,
.max_mode = HPT370_ALLOW_ATA100_5 ? 3 : 2,
.dpll_clk = 48,
.settings = hpt37x_settings
};
static struct hpt_info hpt370a __devinitdata = {
.chip_type = HPT370A,
.max_mode = HPT370_ALLOW_ATA100_5 ? 3 : 2,
.dpll_clk = 48,
.settings = hpt37x_settings
};
static struct hpt_info hpt374 __devinitdata = {
.chip_type = HPT374,
.max_mode = HPT374_ALLOW_ATA133_6 ? 4 : 3,
.dpll_clk = 48,
.settings = hpt37x_settings
};
static struct hpt_info hpt372 __devinitdata = {
.chip_type = HPT372,
.max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3,
.dpll_clk = 55,
.settings = hpt37x_settings
};
static struct hpt_info hpt372a __devinitdata = {
.chip_type = HPT372A,
.max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3,
.dpll_clk = 66,
.settings = hpt37x_settings
};
static struct hpt_info hpt302 __devinitdata = {
.chip_type = HPT302,
.max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3,
.dpll_clk = 66,
.settings = hpt37x_settings
};
static struct hpt_info hpt371 __devinitdata = {
.chip_type = HPT371,
.max_mode = HPT371_ALLOW_ATA133_6 ? 4 : 3,
.dpll_clk = 66,
.settings = hpt37x_settings
};
static struct hpt_info hpt372n __devinitdata = {
.chip_type = HPT372N,
.max_mode = HPT372_ALLOW_ATA133_6 ? 4 : 3,
.dpll_clk = 77,
.settings = hpt37x_settings
};
static struct hpt_info hpt302n __devinitdata = {
.chip_type = HPT302N,
.max_mode = HPT302_ALLOW_ATA133_6 ? 4 : 3,
.dpll_clk = 77,
};
static __devinit u32 hpt_revision (struct pci_dev *dev)
static struct hpt_info hpt371n __devinitdata = {
.chip_type = HPT371N,
.max_mode = HPT371_ALLOW_ATA133_6 ? 4 : 3,
.dpll_clk = 77,
.settings = hpt37x_settings
};
static int check_in_drive_list(ide_drive_t *drive, const char **list)
{
u32 class_rev;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
switch(dev->device) {
/* Remap new 372N onto 372 */
case PCI_DEVICE_ID_TTI_HPT372N:
class_rev = PCI_DEVICE_ID_TTI_HPT372; break;
case PCI_DEVICE_ID_TTI_HPT374:
class_rev = PCI_DEVICE_ID_TTI_HPT374; break;
case PCI_DEVICE_ID_TTI_HPT371:
class_rev = PCI_DEVICE_ID_TTI_HPT371; break;
case PCI_DEVICE_ID_TTI_HPT302:
class_rev = PCI_DEVICE_ID_TTI_HPT302; break;
case PCI_DEVICE_ID_TTI_HPT372:
class_rev = PCI_DEVICE_ID_TTI_HPT372; break;
default:
break;
}
return class_rev;
}
struct hd_driveid *id = drive->id;
static int check_in_drive_lists(ide_drive_t *drive, const char **list);
while (*list)
if (!strcmp(*list++,id->model))
return 1;
return 0;
}
static u8 hpt3xx_ratemask (ide_drive_t *drive)
static u8 hpt3xx_ratemask(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct hpt_info *info = ide_get_hwifdata(hwif);
u8 mode = 0;
/* FIXME: TODO - move this to set info->mode once at boot */
if (info->revision >= 8) { /* HPT374 */
mode = (HPT374_ALLOW_ATA133_6) ? 4 : 3;
} else if (info->revision >= 7) { /* HPT371 */
mode = (HPT371_ALLOW_ATA133_6) ? 4 : 3;
} else if (info->revision >= 6) { /* HPT302 */
mode = (HPT302_ALLOW_ATA133_6) ? 4 : 3;
} else if (info->revision >= 5) { /* HPT372 */
mode = (HPT372_ALLOW_ATA133_6) ? 4 : 3;
} else if (info->revision >= 4) { /* HPT370A */
mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2;
} else if (info->revision >= 3) { /* HPT370 */
mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2;
mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : mode;
} else { /* HPT366 and HPT368 */
mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : 2;
}
struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev);
u8 mode = info->max_mode;
if (!eighty_ninty_three(drive) && mode)
mode = min(mode, (u8)1);
return mode;
......@@ -429,75 +528,61 @@ static u8 hpt3xx_ratemask (ide_drive_t *drive)
* either PIO or UDMA modes 0,4,5
*/
static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed)
static u8 hpt3xx_ratefilter(ide_drive_t *drive, u8 speed)
{
ide_hwif_t *hwif = drive->hwif;
struct hpt_info *info = ide_get_hwifdata(hwif);
struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev);
u8 chip_type = info->chip_type;
u8 mode = hpt3xx_ratemask(drive);
if (drive->media != ide_disk)
return min(speed, (u8)XFER_PIO_4);
switch(mode) {
switch (mode) {
case 0x04:
speed = min(speed, (u8)XFER_UDMA_6);
speed = min_t(u8, speed, XFER_UDMA_6);
break;
case 0x03:
speed = min(speed, (u8)XFER_UDMA_5);
if (info->revision >= 5)
speed = min_t(u8, speed, XFER_UDMA_5);
if (chip_type >= HPT374)
break;
if (check_in_drive_lists(drive, bad_ata100_5))
speed = min(speed, (u8)XFER_UDMA_4);
break;
if (!check_in_drive_list(drive, bad_ata100_5))
goto check_bad_ata33;
/* fall thru */
case 0x02:
speed = min(speed, (u8)XFER_UDMA_4);
/*
* CHECK ME, Does this need to be set to 5 ??
*/
if (info->revision >= 3)
break;
if ((check_in_drive_lists(drive, bad_ata66_4)) ||
(!(HPT366_ALLOW_ATA66_4)))
speed = min(speed, (u8)XFER_UDMA_3);
if ((check_in_drive_lists(drive, bad_ata66_3)) ||
(!(HPT366_ALLOW_ATA66_3)))
speed = min(speed, (u8)XFER_UDMA_2);
break;
speed = min_t(u8, speed, XFER_UDMA_4);
/*
* CHECK ME, Does this need to be changed to HPT374 ??
*/
if (chip_type >= HPT370)
goto check_bad_ata33;
if (HPT366_ALLOW_ATA66_4 &&
!check_in_drive_list(drive, bad_ata66_4))
goto check_bad_ata33;
speed = min_t(u8, speed, XFER_UDMA_3);
if (HPT366_ALLOW_ATA66_3 &&
!check_in_drive_list(drive, bad_ata66_3))
goto check_bad_ata33;
/* fall thru */
case 0x01:
speed = min(speed, (u8)XFER_UDMA_2);
/*
* CHECK ME, Does this need to be set to 5 ??
*/
if (info->revision >= 3)
speed = min_t(u8, speed, XFER_UDMA_2);
check_bad_ata33:
if (chip_type >= HPT370A)
break;
if (check_in_drive_lists(drive, bad_ata33))
speed = min(speed, (u8)XFER_MW_DMA_2);
break;
if (!check_in_drive_list(drive, bad_ata33))
break;
/* fall thru */
case 0x00:
default:
speed = min(speed, (u8)XFER_MW_DMA_2);
speed = min_t(u8, speed, XFER_MW_DMA_2);
break;
}
return speed;
}
static int check_in_drive_lists (ide_drive_t *drive, const char **list)
{
struct hd_driveid *id = drive->id;
if (quirk_drives == list) {
while (*list)
if (strstr(id->model, *list++))
return 1;
} else {
while (*list)
if (!strcmp(*list++,id->model))
return 1;
}
return 0;
}
static u32 pci_bus_clock_list(u8 speed, u32 *chipset_table)
static u32 get_speed_setting(u8 speed, struct hpt_info *info)
{
int i;
......@@ -510,228 +595,161 @@ static u32 pci_bus_clock_list(u8 speed, u32 *chipset_table)
for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++)
if (xfer_speeds[i] == speed)
break;
return chipset_table[i];
/*
* NOTE: info->settings only points to the pointer
* to the list of the actual register values
*/
return (*info->settings)[i];
}
static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = hwif->pci_dev;
struct hpt_info *info = ide_get_hwifdata(hwif);
u8 speed = hpt3xx_ratefilter(drive, xferspeed);
u8 regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
u8 regfast = (hwif->channel) ? 0x55 : 0x51;
u8 drive_fast = 0;
u32 reg1 = 0, reg2 = 0;
/*
* Disable the "fast interrupt" prediction.
*/
pci_read_config_byte(dev, regfast, &drive_fast);
if (drive_fast & 0x80)
pci_write_config_byte(dev, regfast, drive_fast & ~0x80);
reg2 = pci_bus_clock_list(speed, info->speed);
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
struct hpt_info *info = pci_get_drvdata(dev);
u8 speed = hpt3xx_ratefilter(drive, xferspeed);
u8 itr_addr = drive->dn ? 0x44 : 0x40;
u32 itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 :
(speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff);
u32 new_itr = get_speed_setting(speed, info);
u32 old_itr = 0;
/*
* Disable on-chip PIO FIFO/buffer
* (to avoid problems handling I/O errors later)
* Disable on-chip PIO FIFO/buffer (and PIO MST mode as well)
* to avoid problems handling I/O errors later
*/
pci_read_config_dword(dev, regtime, &reg1);
if (speed >= XFER_MW_DMA_0) {
reg2 = (reg2 & ~0xc0000000) | (reg1 & 0xc0000000);
} else {
reg2 = (reg2 & ~0x30070000) | (reg1 & 0x30070000);
}
reg2 &= ~0x80000000;
pci_read_config_dword(dev, itr_addr, &old_itr);
new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask);
new_itr &= ~0xc0000000;
pci_write_config_dword(dev, regtime, reg2);
pci_write_config_dword(dev, itr_addr, new_itr);
return ide_config_drive_speed(drive, speed);
}
static int hpt370_tune_chipset(ide_drive_t *drive, u8 xferspeed)
static int hpt37x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = hwif->pci_dev;
struct hpt_info *info = ide_get_hwifdata(hwif);
u8 speed = hpt3xx_ratefilter(drive, xferspeed);
u8 regfast = (drive->hwif->channel) ? 0x55 : 0x51;
u8 drive_pci = 0x40 + (drive->dn * 4);
u8 new_fast = 0, drive_fast = 0;
u32 list_conf = 0, drive_conf = 0;
u32 conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
/*
* Disable the "fast interrupt" prediction.
* don't holdoff on interrupts. (== 0x01 despite what the docs say)
*/
pci_read_config_byte(dev, regfast, &drive_fast);
new_fast = drive_fast;
if (new_fast & 0x02)
new_fast &= ~0x02;
#ifdef HPT_DELAY_INTERRUPT
if (new_fast & 0x01)
new_fast &= ~0x01;
#else
if ((new_fast & 0x01) == 0)
new_fast |= 0x01;
#endif
if (new_fast != drive_fast)
pci_write_config_byte(dev, regfast, new_fast);
list_conf = pci_bus_clock_list(speed, info->speed);
pci_read_config_dword(dev, drive_pci, &drive_conf);
list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
struct hpt_info *info = pci_get_drvdata(dev);
u8 speed = hpt3xx_ratefilter(drive, xferspeed);
u8 itr_addr = 0x40 + (drive->dn * 4);
u32 itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 :
(speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff);
u32 new_itr = get_speed_setting(speed, info);
u32 old_itr = 0;
pci_read_config_dword(dev, itr_addr, &old_itr);
new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask);
if (speed < XFER_MW_DMA_0)
list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
pci_write_config_dword(dev, drive_pci, list_conf);
new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
pci_write_config_dword(dev, itr_addr, new_itr);
return ide_config_drive_speed(drive, speed);
}
static int hpt372_tune_chipset(ide_drive_t *drive, u8 xferspeed)
static int hpt3xx_tune_chipset(ide_drive_t *drive, u8 speed)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = hwif->pci_dev;
struct hpt_info *info = ide_get_hwifdata(hwif);
u8 speed = hpt3xx_ratefilter(drive, xferspeed);
u8 regfast = (drive->hwif->channel) ? 0x55 : 0x51;
u8 drive_fast = 0, drive_pci = 0x40 + (drive->dn * 4);
u32 list_conf = 0, drive_conf = 0;
u32 conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
/*
* Disable the "fast interrupt" prediction.
* don't holdoff on interrupts. (== 0x01 despite what the docs say)
*/
pci_read_config_byte(dev, regfast, &drive_fast);
drive_fast &= ~0x07;
pci_write_config_byte(dev, regfast, drive_fast);
list_conf = pci_bus_clock_list(speed, info->speed);
pci_read_config_dword(dev, drive_pci, &drive_conf);
list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
if (speed < XFER_MW_DMA_0)
list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
pci_write_config_dword(dev, drive_pci, list_conf);
return ide_config_drive_speed(drive, speed);
}
ide_hwif_t *hwif = HWIF(drive);
struct hpt_info *info = pci_get_drvdata(hwif->pci_dev);
static int hpt3xx_tune_chipset (ide_drive_t *drive, u8 speed)
{
ide_hwif_t *hwif = drive->hwif;
struct hpt_info *info = ide_get_hwifdata(hwif);
if (info->revision >= 8)
return hpt372_tune_chipset(drive, speed); /* not a typo */
else if (info->revision >= 5)
return hpt372_tune_chipset(drive, speed);
else if (info->revision >= 3)
return hpt370_tune_chipset(drive, speed);
if (info->chip_type >= HPT370)
return hpt37x_tune_chipset(drive, speed);
else /* hpt368: hpt_minimum_revision(dev, 2) */
return hpt36x_tune_chipset(drive, speed);
}
static void hpt3xx_tune_drive (ide_drive_t *drive, u8 pio)
static void hpt3xx_tune_drive(ide_drive_t *drive, u8 pio)
{
pio = ide_get_best_pio_mode(drive, 255, pio, NULL);
(void) hpt3xx_tune_chipset(drive, (XFER_PIO_0 + pio));
pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
(void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio);
}
/*
* This allows the configuration of ide_pci chipset registers
* for cards that learn about the drive's UDMA, DMA, PIO capabilities
* after the drive is reported by the OS. Initially for designed for
* after the drive is reported by the OS. Initially designed for
* HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc.
*
* check_in_drive_lists(drive, bad_ata66_4)
* check_in_drive_lists(drive, bad_ata66_3)
* check_in_drive_lists(drive, bad_ata33)
*
*/
static int config_chipset_for_dma (ide_drive_t *drive)
static int config_chipset_for_dma(ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive));
ide_hwif_t *hwif = drive->hwif;
struct hpt_info *info = ide_get_hwifdata(hwif);
if (!speed)
return 0;
/* If we don't have any timings we can't do a lot */
if (info->speed == NULL)
return 0;
(void) hpt3xx_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
static int hpt3xx_quirkproc (ide_drive_t *drive)
static int hpt3xx_quirkproc(ide_drive_t *drive)
{
return ((int) check_in_drive_lists(drive, quirk_drives));
struct hd_driveid *id = drive->id;
const char **list = quirk_drives;
while (*list)
if (strstr(id->model, *list++))
return 1;
return 0;
}
static void hpt3xx_intrproc (ide_drive_t *drive)
static void hpt3xx_intrproc(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
ide_hwif_t *hwif = HWIF(drive);
if (drive->quirk_list)
return;
/* drives in the quirk_list may not like intr setups/cleanups */
hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG);
hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
}
static void hpt3xx_maskproc (ide_drive_t *drive, int mask)
static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
{
ide_hwif_t *hwif = drive->hwif;
struct hpt_info *info = ide_get_hwifdata(hwif);
struct pci_dev *dev = hwif->pci_dev;
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
struct hpt_info *info = pci_get_drvdata(dev);
if (drive->quirk_list) {
if (info->revision >= 3) {
u8 reg5a = 0;
pci_read_config_byte(dev, 0x5a, &reg5a);
if (((reg5a & 0x10) >> 4) != mask)
pci_write_config_byte(dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10));
if (info->chip_type >= HPT370) {
u8 scr1 = 0;
pci_read_config_byte(dev, 0x5a, &scr1);
if (((scr1 & 0x10) >> 4) != mask) {
if (mask)
scr1 |= 0x10;
else
scr1 &= ~0x10;
pci_write_config_byte(dev, 0x5a, scr1);
}
} else {
if (mask) {
if (mask)
disable_irq(hwif->irq);
} else {
enable_irq(hwif->irq);
}
else
enable_irq (hwif->irq);
}
} else {
if (IDE_CONTROL_REG)
hwif->OUTB(mask ? (drive->ctl | 2) :
(drive->ctl & ~2),
IDE_CONTROL_REG);
}
} else
hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
IDE_CONTROL_REG);
}
static int hpt366_config_drive_xfer_rate (ide_drive_t *drive)
static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
ide_hwif_t *hwif = HWIF(drive);
struct hd_driveid *id = drive->id;
drive->init_speed = 0;
if ((id->capability & 1) && drive->autodma) {
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
goto fast_ata_pio;
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
hpt3xx_tune_drive(drive, 5);
hpt3xx_tune_drive(drive, 255);
return hwif->ide_dma_off_quietly(drive);
}
/* IORDY not supported */
......@@ -739,31 +757,48 @@ static int hpt366_config_drive_xfer_rate (ide_drive_t *drive)
}
/*
* This is specific to the HPT366 UDMA bios chipset
* This is specific to the HPT366 UDMA chipset
* by HighPoint|Triones Technologies, Inc.
*/
static int hpt366_ide_dma_lostirq (ide_drive_t *drive)
static int hpt366_ide_dma_lostirq(ide_drive_t *drive)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
u8 reg50h = 0, reg52h = 0, reg5ah = 0;
pci_read_config_byte(dev, 0x50, &reg50h);
pci_read_config_byte(dev, 0x52, &reg52h);
pci_read_config_byte(dev, 0x5a, &reg5ah);
printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n",
drive->name, __FUNCTION__, reg50h, reg52h, reg5ah);
if (reg5ah & 0x10)
pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
struct pci_dev *dev = HWIF(drive)->pci_dev;
u8 mcr1 = 0, mcr3 = 0, scr1 = 0;
pci_read_config_byte(dev, 0x50, &mcr1);
pci_read_config_byte(dev, 0x52, &mcr3);
pci_read_config_byte(dev, 0x5a, &scr1);
printk("%s: (%s) mcr1=0x%02x, mcr3=0x%02x, scr1=0x%02x\n",
drive->name, __FUNCTION__, mcr1, mcr3, scr1);
if (scr1 & 0x10)
pci_write_config_byte(dev, 0x5a, scr1 & ~0x10);
return __ide_dma_lostirq(drive);
}
static void hpt370_clear_engine (ide_drive_t *drive)
static void hpt370_clear_engine(ide_drive_t *drive)
{
u8 regstate = HWIF(drive)->channel ? 0x54 : 0x50;
pci_write_config_byte(HWIF(drive)->pci_dev, regstate, 0x37);
ide_hwif_t *hwif = HWIF(drive);
pci_write_config_byte(hwif->pci_dev, hwif->select_data, 0x37);
udelay(10);
}
static void hpt370_irq_timeout(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u16 bfifo = 0;
u8 dma_cmd;
pci_read_config_word(hwif->pci_dev, hwif->select_data + 2, &bfifo);
printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff);
/* get DMA command mode */
dma_cmd = hwif->INB(hwif->dma_command);
/* stop DMA */
hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command);
hpt370_clear_engine(drive);
}
static void hpt370_ide_dma_start(ide_drive_t *drive)
{
#ifdef HPT_RESET_STATE_ENGINE
......@@ -772,64 +807,35 @@ static void hpt370_ide_dma_start(ide_drive_t *drive)
ide_dma_start(drive);
}
static int hpt370_ide_dma_end (ide_drive_t *drive)
static int hpt370_ide_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 dma_stat = hwif->INB(hwif->dma_status);
u8 dma_stat = hwif->INB(hwif->dma_status);
if (dma_stat & 0x01) {
/* wait a little */
udelay(20);
dma_stat = hwif->INB(hwif->dma_status);
if (dma_stat & 0x01)
hpt370_irq_timeout(drive);
}
if ((dma_stat & 0x01) != 0)
/* fallthrough */
(void) HWIF(drive)->ide_dma_timeout(drive);
return __ide_dma_end(drive);
}
static void hpt370_lostirq_timeout (ide_drive_t *drive)
static int hpt370_ide_dma_timeout(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u8 bfifo = 0, reginfo = hwif->channel ? 0x56 : 0x52;
u8 dma_stat = 0, dma_cmd = 0;
pci_read_config_byte(HWIF(drive)->pci_dev, reginfo, &bfifo);
printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo);
hpt370_clear_engine(drive);
/* get dma command mode */
dma_cmd = hwif->INB(hwif->dma_command);
/* stop dma */
hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command);
dma_stat = hwif->INB(hwif->dma_status);
/* clear errors */
hwif->OUTB(dma_stat | 0x6, hwif->dma_status);
}
static int hpt370_ide_dma_timeout (ide_drive_t *drive)
{
hpt370_lostirq_timeout(drive);
hpt370_clear_engine(drive);
hpt370_irq_timeout(drive);
return __ide_dma_timeout(drive);
}
static int hpt370_ide_dma_lostirq (ide_drive_t *drive)
{
hpt370_lostirq_timeout(drive);
hpt370_clear_engine(drive);
return __ide_dma_lostirq(drive);
}
/* returns 1 if DMA IRQ issued, 0 otherwise */
static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
u16 bfifo = 0;
u8 reginfo = hwif->channel ? 0x56 : 0x52;
u8 dma_stat;
u8 dma_stat;
pci_read_config_word(hwif->pci_dev, reginfo, &bfifo);
pci_read_config_word(hwif->pci_dev, hwif->select_data + 2, &bfifo);
if (bfifo & 0x1FF) {
// printk("%s: %d bytes in FIFO\n", drive->name, bfifo);
return 0;
......@@ -837,7 +843,7 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
dma_stat = hwif->INB(hwif->dma_status);
/* return 1 if INTR asserted */
if ((dma_stat & 4) == 4)
if (dma_stat & 4)
return 1;
if (!drive->waiting_for_dma)
......@@ -846,17 +852,17 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
return 0;
}
static int hpt374_ide_dma_end (ide_drive_t *drive)
static int hpt374_ide_dma_end(ide_drive_t *drive)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
ide_hwif_t *hwif = HWIF(drive);
u8 msc_stat = 0, mscreg = hwif->channel ? 0x54 : 0x50;
u8 bwsr_stat = 0, bwsr_mask = hwif->channel ? 0x02 : 0x01;
pci_read_config_byte(dev, 0x6a, &bwsr_stat);
pci_read_config_byte(dev, mscreg, &msc_stat);
if ((bwsr_stat & bwsr_mask) == bwsr_mask)
pci_write_config_byte(dev, mscreg, msc_stat|0x30);
struct pci_dev *dev = hwif->pci_dev;
u8 mcr = 0, mcr_addr = hwif->select_data;
u8 bwsr = 0, mask = hwif->channel ? 0x02 : 0x01;
pci_read_config_byte(dev, 0x6a, &bwsr);
pci_read_config_byte(dev, mcr_addr, &mcr);
if (bwsr & mask)
pci_write_config_byte(dev, mcr_addr, mcr | 0x30);
return __ide_dma_end(drive);
}
......@@ -866,40 +872,37 @@ static int hpt374_ide_dma_end (ide_drive_t *drive)
* @mode: clocking mode (0x21 for write, 0x23 otherwise)
*
* Switch the DPLL clock on the HPT3xxN devices. This is a right mess.
* NOTE: avoid touching the disabled primary channel on HPT371N -- it
* doesn't physically exist anyway...
*/
static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
{
u8 mcr1, scr2 = hwif->INB(hwif->dma_master + 0x7b);
u8 scr2 = hwif->INB(hwif->dma_master + 0x7b);
if ((scr2 & 0x7f) == mode)
return;
/* MISC. control register 1 has the channel enable bit... */
mcr1 = hwif->INB(hwif->dma_master + 0x70);
/* Tristate the bus */
if (mcr1 & 0x04)
hwif->OUTB(0x80, hwif->dma_master + 0x73);
hwif->OUTB(0x80, hwif->dma_master + 0x73);
hwif->OUTB(0x80, hwif->dma_master + 0x77);
/* Switch clock and reset channels */
hwif->OUTB(mode, hwif->dma_master + 0x7b);
hwif->OUTB(0xc0, hwif->dma_master + 0x79);
/* Reset state machines */
if (mcr1 & 0x04)
hwif->OUTB(0x37, hwif->dma_master + 0x70);
hwif->OUTB(0x37, hwif->dma_master + 0x74);
/*
* Reset the state machines.
* NOTE: avoid accidentally enabling the disabled channels.
*/
hwif->OUTB(hwif->INB(hwif->dma_master + 0x70) | 0x32,
hwif->dma_master + 0x70);
hwif->OUTB(hwif->INB(hwif->dma_master + 0x74) | 0x32,
hwif->dma_master + 0x74);
/* Complete reset */
hwif->OUTB(0x00, hwif->dma_master + 0x79);
/* Reconnect channels to bus */
if (mcr1 & 0x04)
hwif->OUTB(0x00, hwif->dma_master + 0x73);
hwif->OUTB(0x00, hwif->dma_master + 0x73);
hwif->OUTB(0x00, hwif->dma_master + 0x77);
}
......@@ -914,14 +917,12 @@ static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
{
ide_hwif_t *hwif = HWIF(drive);
u8 wantclock = rq_data_dir(rq) ? 0x23 : 0x21;
hpt3xxn_set_clock(hwif, wantclock);
hpt3xxn_set_clock(HWIF(drive), rq_data_dir(rq) ? 0x23 : 0x21);
}
/*
* Set/get power state for a drive.
* NOTE: affects both drives on each channel.
*
* When we turn the power back on, we need to re-initialize things.
*/
......@@ -929,26 +930,18 @@ static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
static int hpt3xx_busproc(ide_drive_t *drive, int state)
{
ide_hwif_t *hwif = drive->hwif;
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 tristate, resetmask, bus_reg = 0;
u16 tri_reg = 0;
u8 mcr_addr = hwif->select_data + 2;
u8 resetmask = hwif->channel ? 0x80 : 0x40;
u8 bsr2 = 0;
u16 mcr = 0;
hwif->bus_state = state;
if (hwif->channel) {
/* secondary channel */
tristate = 0x56;
resetmask = 0x80;
} else {
/* primary channel */
tristate = 0x52;
resetmask = 0x40;
}
/* Grab the status. */
pci_read_config_word(dev, tristate, &tri_reg);
pci_read_config_byte(dev, 0x59, &bus_reg);
pci_read_config_word(dev, mcr_addr, &mcr);
pci_read_config_byte(dev, 0x59, &bsr2);
/*
* Set the state. We don't set it if we don't need to do so.
......@@ -956,22 +949,22 @@ static int hpt3xx_busproc(ide_drive_t *drive, int state)
*/
switch (state) {
case BUSSTATE_ON:
if (!(bus_reg & resetmask))
if (!(bsr2 & resetmask))
return 0;
hwif->drives[0].failures = hwif->drives[1].failures = 0;
pci_write_config_byte(dev, 0x59, bus_reg & ~resetmask);
pci_write_config_word(dev, tristate, tri_reg & ~TRISTATE_BIT);
pci_write_config_byte(dev, 0x59, bsr2 & ~resetmask);
pci_write_config_word(dev, mcr_addr, mcr & ~TRISTATE_BIT);
return 0;
case BUSSTATE_OFF:
if ((bus_reg & resetmask) && !(tri_reg & TRISTATE_BIT))
if ((bsr2 & resetmask) && !(mcr & TRISTATE_BIT))
return 0;
tri_reg &= ~TRISTATE_BIT;
mcr &= ~TRISTATE_BIT;
break;
case BUSSTATE_TRISTATE:
if ((bus_reg & resetmask) && (tri_reg & TRISTATE_BIT))
if ((bsr2 & resetmask) && (mcr & TRISTATE_BIT))
return 0;
tri_reg |= TRISTATE_BIT;
mcr |= TRISTATE_BIT;
break;
default:
return -EINVAL;
......@@ -980,268 +973,320 @@ static int hpt3xx_busproc(ide_drive_t *drive, int state)
hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
pci_write_config_word(dev, tristate, tri_reg);
pci_write_config_byte(dev, 0x59, bus_reg | resetmask);
pci_write_config_word(dev, mcr_addr, mcr);
pci_write_config_byte(dev, 0x59, bsr2 | resetmask);
return 0;
}
static void __devinit hpt366_clocking(ide_hwif_t *hwif)
/**
* hpt37x_calibrate_dpll - calibrate the DPLL
* @dev: PCI device
*
* Perform a calibration cycle on the DPLL.
* Returns 1 if this succeeds
*/
static int __devinit hpt37x_calibrate_dpll(struct pci_dev *dev, u16 f_low, u16 f_high)
{
u32 reg1 = 0;
struct hpt_info *info = ide_get_hwifdata(hwif);
u32 dpll = (f_high << 16) | f_low | 0x100;
u8 scr2;
int i;
pci_read_config_dword(hwif->pci_dev, 0x40, &reg1);
pci_write_config_dword(dev, 0x5c, dpll);
/* detect bus speed by looking at control reg timing: */
switch((reg1 >> 8) & 7) {
case 5:
info->speed = forty_base_hpt36x;
break;
case 9:
info->speed = twenty_five_base_hpt36x;
break;
case 7:
default:
info->speed = thirty_three_base_hpt36x;
/* Wait for oscillator ready */
for(i = 0; i < 0x5000; ++i) {
udelay(50);
pci_read_config_byte(dev, 0x5b, &scr2);
if (scr2 & 0x80)
break;
}
/* See if it stays ready (we'll just bail out if it's not yet) */
for(i = 0; i < 0x1000; ++i) {
pci_read_config_byte(dev, 0x5b, &scr2);
/* DPLL destabilized? */
if(!(scr2 & 0x80))
return 0;
}
/* Turn off tuning, we have the DPLL set */
pci_read_config_dword (dev, 0x5c, &dpll);
pci_write_config_dword(dev, 0x5c, (dpll & ~0x100));
return 1;
}
static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name)
{
struct hpt_info *info = ide_get_hwifdata(hwif);
struct pci_dev *dev = hwif->pci_dev;
int adjust, i;
u16 freq = 0;
u32 pll, temp = 0;
u8 reg5bh = 0, mcr1 = 0;
struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL);
unsigned long io_base = pci_resource_start(dev, 4);
u8 pci_clk, dpll_clk = 0; /* PCI and DPLL clock in MHz */
enum ata_clock clock;
if (info == NULL) {
printk(KERN_ERR "%s: out of memory!\n", name);
return -ENOMEM;
}
/*
* default to pci clock. make sure MA15/16 are set to output
* to prevent drives having problems with 40-pin cables. Needed
* for some drives such as IBM-DTLA which will not enter ready
* state on reset when PDIAG is a input.
*
* ToDo: should we set 0x21 when using PLL mode ?
* Copy everything from a static "template" structure
* to just allocated per-chip hpt_info structure.
*/
pci_write_config_byte(dev, 0x5b, 0x23);
*info = *(struct hpt_info *)pci_get_drvdata(dev);
/*
* We'll have to read f_CNT value in order to determine
* the PCI clock frequency according to the following ratio:
*
* f_CNT = Fpci * 192 / Fdpll
*
* First try reading the register in which the HighPoint BIOS
* saves f_CNT value before reprogramming the DPLL from its
* default setting (which differs for the various chips).
* NOTE: This register is only accessible via I/O space.
*
* In case the signature check fails, we'll have to resort to
* reading the f_CNT register itself in hopes that nobody has
* touched the DPLL yet...
* FIXME: Not portable. Also, why do we enable the ROM in the first place?
* We don't seem to be using it.
*/
temp = inl(pci_resource_start(dev, 4) + 0x90);
if ((temp & 0xFFFFF000) != 0xABCDE000) {
printk(KERN_WARNING "HPT37X: no clock data saved by BIOS\n");
/* Calculate the average value of f_CNT */
for (temp = i = 0; i < 128; i++) {
pci_read_config_word(dev, 0x78, &freq);
temp += freq & 0x1ff;
mdelay(1);
}
freq = temp / 128;
} else
freq = temp & 0x1ff;
if (dev->resource[PCI_ROM_RESOURCE].start)
pci_write_config_dword(dev, PCI_ROM_ADDRESS,
dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
/*
* HPT3xxN chips use different PCI clock information.
* Currently we always set up the PLL for them.
* First, try to estimate the PCI clock frequency...
*/
if (info->chip_type >= HPT370) {
u8 scr1 = 0;
u16 f_cnt = 0;
u32 temp = 0;
if (info->flags & IS_3xxN) {
if(freq < 0x55)
pll = F_LOW_PCI_33;
else if(freq < 0x70)
pll = F_LOW_PCI_40;
else if(freq < 0x7F)
pll = F_LOW_PCI_50;
else
pll = F_LOW_PCI_66;
/* Interrupt force enable. */
pci_read_config_byte(dev, 0x5a, &scr1);
if (scr1 & 0x10)
pci_write_config_byte(dev, 0x5a, scr1 & ~0x10);
printk(KERN_INFO "HPT3xxN detected, FREQ: %d, PLL: %d\n", freq, pll);
}
else
{
if(freq < 0x9C)
pll = F_LOW_PCI_33;
else if(freq < 0xb0)
pll = F_LOW_PCI_40;
else if(freq <0xc8)
pll = F_LOW_PCI_50;
/*
* HighPoint does this for HPT372A.
* NOTE: This register is only writeable via I/O space.
*/
if (info->chip_type == HPT372A)
outb(0x0e, io_base + 0x9c);
/*
* Default to PCI clock. Make sure MA15/16 are set to output
* to prevent drives having problems with 40-pin cables.
*/
pci_write_config_byte(dev, 0x5b, 0x23);
/*
* We'll have to read f_CNT value in order to determine
* the PCI clock frequency according to the following ratio:
*
* f_CNT = Fpci * 192 / Fdpll
*
* First try reading the register in which the HighPoint BIOS
* saves f_CNT value before reprogramming the DPLL from its
* default setting (which differs for the various chips).
* NOTE: This register is only accessible via I/O space.
*
* In case the signature check fails, we'll have to resort to
* reading the f_CNT register itself in hopes that nobody has
* touched the DPLL yet...
*/
temp = inl(io_base + 0x90);
if ((temp & 0xFFFFF000) != 0xABCDE000) {
int i;
printk(KERN_WARNING "%s: no clock data saved by BIOS\n",
name);
/* Calculate the average value of f_CNT. */
for (temp = i = 0; i < 128; i++) {
pci_read_config_word(dev, 0x78, &f_cnt);
temp += f_cnt & 0x1ff;
mdelay(1);
}
f_cnt = temp / 128;
} else
f_cnt = temp & 0x1ff;
dpll_clk = info->dpll_clk;
pci_clk = (f_cnt * dpll_clk) / 192;
/* Clamp PCI clock to bands. */
if (pci_clk < 40)
pci_clk = 33;
else if(pci_clk < 45)
pci_clk = 40;
else if(pci_clk < 55)
pci_clk = 50;
else
pll = F_LOW_PCI_66;
if (pll == F_LOW_PCI_33) {
info->speed = thirty_three_base_hpt37x;
printk(KERN_DEBUG "HPT37X: using 33MHz PCI clock\n");
} else if (pll == F_LOW_PCI_40) {
/* Unsupported */
} else if (pll == F_LOW_PCI_50) {
info->speed = fifty_base_hpt37x;
printk(KERN_DEBUG "HPT37X: using 50MHz PCI clock\n");
} else {
info->speed = sixty_six_base_hpt37x;
printk(KERN_DEBUG "HPT37X: using 66MHz PCI clock\n");
pci_clk = 66;
printk(KERN_INFO "%s: DPLL base: %d MHz, f_CNT: %d, "
"assuming %d MHz PCI\n", name, dpll_clk, f_cnt, pci_clk);
} else {
u32 itr1 = 0;
pci_read_config_dword(dev, 0x40, &itr1);
/* Detect PCI clock by looking at cmd_high_time. */
switch((itr1 >> 8) & 0x07) {
case 0x09:
pci_clk = 40;
break;
case 0x05:
pci_clk = 25;
break;
case 0x07:
default:
pci_clk = 33;
break;
}
}
if (pll == F_LOW_PCI_66)
info->flags |= PCI_66MHZ;
/* Let's assume we'll use PCI clock for the ATA clock... */
switch (pci_clk) {
case 25:
clock = ATA_CLOCK_25MHZ;
break;
case 33:
default:
clock = ATA_CLOCK_33MHZ;
break;
case 40:
clock = ATA_CLOCK_40MHZ;
break;
case 50:
clock = ATA_CLOCK_50MHZ;
break;
case 66:
clock = ATA_CLOCK_66MHZ;
break;
}
/*
* only try the pll if we don't have a table for the clock
* speed that we're running at. NOTE: the internal PLL will
* result in slow reads when using a 33MHz PCI clock. we also
* don't like to use the PLL because it will cause glitches
* on PRST/SRST when the HPT state engine gets reset.
* Only try the DPLL if we don't have a table for the PCI clock that
* we are running at for HPT370/A, always use it for anything newer...
*
* ToDo: Use 66MHz PLL when ATA133 devices are present on a
* 372 device so we can get ATA133 support
* NOTE: Using the internal DPLL results in slow reads on 33 MHz PCI.
* We also don't like using the DPLL because this causes glitches
* on PRST-/SRST- when the state engine gets reset...
*/
if (info->speed)
goto init_hpt37X_done;
if (info->chip_type >= HPT374 || info->settings[clock] == NULL) {
u16 f_low, delta = pci_clk < 50 ? 2 : 4;
int adjust;
/*
* Select 66 MHz DPLL clock only if UltraATA/133 mode is
* supported/enabled, use 50 MHz DPLL clock otherwise...
*/
if (info->max_mode == 0x04) {
dpll_clk = 66;
clock = ATA_CLOCK_66MHZ;
} else if (dpll_clk) { /* HPT36x chips don't have DPLL */
dpll_clk = 50;
clock = ATA_CLOCK_50MHZ;
}
info->flags |= PLL_MODE;
/*
* Adjust the PLL based upon the PCI clock, enable it, and
* wait for stabilization...
*/
adjust = 0;
freq = (pll < F_LOW_PCI_50) ? 2 : 4;
while (adjust++ < 6) {
pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 |
pll | 0x100);
/* wait for clock stabilization */
for (i = 0; i < 0x50000; i++) {
pci_read_config_byte(dev, 0x5b, &reg5bh);
if (reg5bh & 0x80) {
/* spin looking for the clock to destabilize */
for (i = 0; i < 0x1000; ++i) {
pci_read_config_byte(dev, 0x5b,
&reg5bh);
if ((reg5bh & 0x80) == 0)
goto pll_recal;
}
pci_read_config_dword(dev, 0x5c, &pll);
pci_write_config_dword(dev, 0x5c,
pll & ~0x100);
pci_write_config_byte(dev, 0x5b, 0x21);
info->speed = fifty_base_hpt37x;
printk("HPT37X: using 50MHz internal PLL\n");
goto init_hpt37X_done;
}
if (info->settings[clock] == NULL) {
printk(KERN_ERR "%s: unknown bus timing!\n", name);
kfree(info);
return -EIO;
}
pll_recal:
if (adjust & 1)
pll -= (adjust >> 1);
else
pll += (adjust >> 1);
}
init_hpt37X_done:
if (!info->speed)
printk(KERN_ERR "HPT37x%s: unknown bus timing [%d %d].\n",
(info->flags & IS_3xxN) ? "N" : "", pll, freq);
/*
* Reset the state engines.
* NOTE: avoid accidentally enabling the primary channel on HPT371N.
*/
pci_read_config_byte(dev, 0x50, &mcr1);
if (mcr1 & 0x04)
pci_write_config_byte(dev, 0x50, 0x37);
pci_write_config_byte(dev, 0x54, 0x37);
udelay(100);
}
/* Select the DPLL clock. */
pci_write_config_byte(dev, 0x5b, 0x21);
static int __devinit init_hpt37x(struct pci_dev *dev)
{
u8 reg5ah;
/*
* Adjust the DPLL based upon PCI clock, enable it,
* and wait for stabilization...
*/
f_low = (pci_clk * 48) / dpll_clk;
pci_read_config_byte(dev, 0x5a, &reg5ah);
/* interrupt force enable */
pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10));
return 0;
}
for (adjust = 0; adjust < 8; adjust++) {
if(hpt37x_calibrate_dpll(dev, f_low, f_low + delta))
break;
static int __devinit init_hpt366(struct pci_dev *dev)
{
u32 reg1 = 0;
u8 drive_fast = 0;
/*
* See if it'll settle at a fractionally different clock
*/
if (adjust & 1)
f_low -= adjust >> 1;
else
f_low += adjust >> 1;
}
if (adjust == 8) {
printk(KERN_ERR "%s: DPLL did not stabilize!\n", name);
kfree(info);
return -EIO;
}
/*
* Disable the "fast interrupt" prediction.
*/
pci_read_config_byte(dev, 0x51, &drive_fast);
if (drive_fast & 0x80)
pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
pci_read_config_dword(dev, 0x40, &reg1);
return 0;
}
printk("%s: using %d MHz DPLL clock\n", name, dpll_clk);
} else {
/* Mark the fact that we're not using the DPLL. */
dpll_clk = 0;
static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name)
{
int ret = 0;
printk("%s: using %d MHz PCI clock\n", name, pci_clk);
}
/*
* FIXME: Not portable. Also, why do we enable the ROM in the first place?
* We don't seem to be using it.
* Advance the table pointer to a slot which points to the list
* of the register values settings matching the clock being used.
*/
if (dev->resource[PCI_ROM_RESOURCE].start)
pci_write_config_dword(dev, PCI_ROM_ADDRESS,
dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
info->settings += clock;
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
/* Store the clock frequencies. */
info->dpll_clk = dpll_clk;
info->pci_clk = pci_clk;
if (hpt_revision(dev) >= 3)
ret = init_hpt37x(dev);
else
ret = init_hpt366(dev);
/* Point to this chip's own instance of the hpt_info structure. */
pci_set_drvdata(dev, info);
if (ret)
return ret;
if (info->chip_type >= HPT370) {
u8 mcr1, mcr4;
/*
* Reset the state engines.
* NOTE: Avoid accidentally enabling the disabled channels.
*/
pci_read_config_byte (dev, 0x50, &mcr1);
pci_read_config_byte (dev, 0x54, &mcr4);
pci_write_config_byte(dev, 0x50, (mcr1 | 0x32));
pci_write_config_byte(dev, 0x54, (mcr4 | 0x32));
udelay(100);
}
/*
* On HPT371N, if ATA clock is 66 MHz we must set bit 2 in
* the MISC. register to stretch the UltraDMA Tss timing.
* NOTE: This register is only writeable via I/O space.
*/
if (info->chip_type == HPT371N && clock == ATA_CLOCK_66MHZ)
outb(inb(io_base + 0x9c) | 0x04, io_base + 0x9c);
return dev->irq;
}
static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
struct hpt_info *info = ide_get_hwifdata(hwif);
u8 ata66 = 0, regmask = (hwif->channel) ? 0x01 : 0x02;
struct pci_dev *dev = hwif->pci_dev;
struct hpt_info *info = pci_get_drvdata(dev);
int serialize = HPT_SERIALIZE_IO;
u8 scr1 = 0, ata66 = (hwif->channel) ? 0x01 : 0x02;
u8 chip_type = info->chip_type;
u8 new_mcr, old_mcr = 0;
/* Cache the channel's MISC. control registers' offset */
hwif->select_data = hwif->channel ? 0x54 : 0x50;
hwif->tuneproc = &hpt3xx_tune_drive;
hwif->speedproc = &hpt3xx_tune_chipset;
hwif->quirkproc = &hpt3xx_quirkproc;
hwif->intrproc = &hpt3xx_intrproc;
hwif->maskproc = &hpt3xx_maskproc;
hwif->busproc = &hpt3xx_busproc;
/*
* HPT3xxN chips have some complications:
*
* - on 33 MHz PCI we must clock switch
* - on 66 MHz PCI we must NOT use the PCI clock
*/
if ((info->flags & (IS_3xxN | PCI_66MHZ)) == IS_3xxN) {
if (chip_type >= HPT372N && info->dpll_clk && info->pci_clk < 66) {
/*
* Clock is shared between the channels,
* so we'll have to serialize them... :-(
......@@ -1250,200 +1295,171 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
hwif->rw_disk = &hpt3xxn_rw_disk;
}
/* Serialize access to this device if needed */
if (serialize && hwif->mate)
hwif->serialized = hwif->mate->serialized = 1;
/*
* Disable the "fast interrupt" prediction. Don't hold off
* on interrupts. (== 0x01 despite what the docs say)
*/
pci_read_config_byte(dev, hwif->select_data + 1, &old_mcr);
if (info->chip_type >= HPT374)
new_mcr = old_mcr & ~0x07;
else if (info->chip_type >= HPT370) {
new_mcr = old_mcr;
new_mcr &= ~0x02;
#ifdef HPT_DELAY_INTERRUPT
new_mcr &= ~0x01;
#else
new_mcr |= 0x01;
#endif
} else /* HPT366 and HPT368 */
new_mcr = old_mcr & ~0x80;
if (new_mcr != old_mcr)
pci_write_config_byte(dev, hwif->select_data + 1, new_mcr);
if (!hwif->dma_base) {
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
return;
}
hwif->ultra_mask = 0x7f;
hwif->mwdma_mask = 0x07;
/*
* The HPT37x uses the CBLID pins as outputs for MA15/MA16
* address lines to access an external eeprom. To read valid
* address lines to access an external EEPROM. To read valid
* cable detect state the pins must be enabled as inputs.
*/
if (info->revision >= 8 && (PCI_FUNC(dev->devfn) & 1)) {
if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) {
/*
* HPT374 PCI function 1
* - set bit 15 of reg 0x52 to enable TCBLID as input
* - set bit 15 of reg 0x56 to enable FCBLID as input
*/
u16 mcr3, mcr6;
pci_read_config_word(dev, 0x52, &mcr3);
pci_read_config_word(dev, 0x56, &mcr6);
pci_write_config_word(dev, 0x52, mcr3 | 0x8000);
pci_write_config_word(dev, 0x56, mcr6 | 0x8000);
u8 mcr_addr = hwif->select_data + 2;
u16 mcr;
pci_read_config_word (dev, mcr_addr, &mcr);
pci_write_config_word(dev, mcr_addr, (mcr | 0x8000));
/* now read cable id register */
pci_read_config_byte(dev, 0x5a, &ata66);
pci_write_config_word(dev, 0x52, mcr3);
pci_write_config_word(dev, 0x56, mcr6);
} else if (info->revision >= 3) {
pci_read_config_byte (dev, 0x5a, &scr1);
pci_write_config_word(dev, mcr_addr, mcr);
} else if (chip_type >= HPT370) {
/*
* HPT370/372 and 374 pcifn 0
* - clear bit 0 of 0x5b to enable P/SCBLID as inputs
* - clear bit 0 of reg 0x5b to enable P/SCBLID as inputs
*/
u8 scr2;
pci_read_config_byte(dev, 0x5b, &scr2);
pci_write_config_byte(dev, 0x5b, scr2 & ~1);
/* now read cable id register */
pci_read_config_byte(dev, 0x5a, &ata66);
pci_write_config_byte(dev, 0x5b, scr2);
} else {
pci_read_config_byte(dev, 0x5a, &ata66);
}
u8 scr2 = 0;
#ifdef DEBUG
printk("HPT366: reg5ah=0x%02x ATA-%s Cable Port%d\n",
ata66, (ata66 & regmask) ? "33" : "66",
PCI_FUNC(hwif->pci_dev->devfn));
#endif /* DEBUG */
/* Serialize access to this device */
if (serialize && hwif->mate)
hwif->serialized = hwif->mate->serialized = 1;
pci_read_config_byte (dev, 0x5b, &scr2);
pci_write_config_byte(dev, 0x5b, (scr2 & ~1));
/* now read cable id register */
pci_read_config_byte (dev, 0x5a, &scr1);
pci_write_config_byte(dev, 0x5b, scr2);
} else
pci_read_config_byte (dev, 0x5a, &scr1);
/*
* Set up ioctl for power status.
* NOTE: power affects both drives on each channel.
*/
hwif->busproc = &hpt3xx_busproc;
if (!hwif->udma_four)
hwif->udma_four = (scr1 & ata66) ? 0 : 1;
if (!hwif->dma_base) {
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
return;
}
hwif->ide_dma_check = &hpt366_config_drive_xfer_rate;
hwif->ultra_mask = 0x7f;
hwif->mwdma_mask = 0x07;
if (!(hwif->udma_four))
hwif->udma_four = ((ata66 & regmask) ? 0 : 1);
hwif->ide_dma_check = &hpt366_config_drive_xfer_rate;
if (info->revision >= 8) {
hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;
hwif->ide_dma_end = &hpt374_ide_dma_end;
} else if (info->revision >= 5) {
hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;
hwif->ide_dma_end = &hpt374_ide_dma_end;
} else if (info->revision >= 3) {
hwif->dma_start = &hpt370_ide_dma_start;
hwif->ide_dma_end = &hpt370_ide_dma_end;
hwif->ide_dma_timeout = &hpt370_ide_dma_timeout;
hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq;
} else if (info->revision >= 2)
hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;
else
hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;
if (chip_type >= HPT374) {
hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;
hwif->ide_dma_end = &hpt374_ide_dma_end;
} else if (chip_type >= HPT370) {
hwif->dma_start = &hpt370_ide_dma_start;
hwif->ide_dma_end = &hpt370_ide_dma_end;
hwif->ide_dma_timeout = &hpt370_ide_dma_timeout;
} else
hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
}
static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
{
struct hpt_info *info = ide_get_hwifdata(hwif);
u8 masterdma = 0, slavedma = 0;
u8 dma_new = 0, dma_old = 0;
u8 primary = hwif->channel ? 0x4b : 0x43;
u8 secondary = hwif->channel ? 0x4f : 0x47;
struct pci_dev *dev = hwif->pci_dev;
u8 masterdma = 0, slavedma = 0;
u8 dma_new = 0, dma_old = 0;
unsigned long flags;
if (!dmabase)
return;
if(info->speed == NULL) {
printk(KERN_WARNING "hpt366: no known IDE timings, disabling DMA.\n");
return;
}
dma_old = hwif->INB(dmabase+2);
dma_old = hwif->INB(dmabase + 2);
local_irq_save(flags);
dma_new = dma_old;
pci_read_config_byte(hwif->pci_dev, primary, &masterdma);
pci_read_config_byte(hwif->pci_dev, secondary, &slavedma);
pci_read_config_byte(dev, hwif->channel ? 0x4b : 0x43, &masterdma);
pci_read_config_byte(dev, hwif->channel ? 0x4f : 0x47, &slavedma);
if (masterdma & 0x30) dma_new |= 0x20;
if (slavedma & 0x30) dma_new |= 0x40;
if ( slavedma & 0x30) dma_new |= 0x40;
if (dma_new != dma_old)
hwif->OUTB(dma_new, dmabase+2);
hwif->OUTB(dma_new, dmabase + 2);
local_irq_restore(flags);
ide_setup_dma(hwif, dmabase, 8);
}
/*
* We "borrow" this hook in order to set the data structures
* up early enough before dma or init_hwif calls are made.
*/
static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
{
struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL);
struct pci_dev *dev = hwif->pci_dev;
u16 did = dev->device;
u8 rid = 0;
if(info == NULL) {
printk(KERN_WARNING "hpt366: out of memory.\n");
return;
}
ide_set_hwifdata(hwif, info);
/* Avoid doing the same thing twice. */
if (hwif->channel && hwif->mate) {
memcpy(info, ide_get_hwifdata(hwif->mate), sizeof(struct hpt_info));
return;
}
pci_read_config_byte(dev, PCI_CLASS_REVISION, &rid);
if (( did == PCI_DEVICE_ID_TTI_HPT366 && rid == 6) ||
((did == PCI_DEVICE_ID_TTI_HPT372 ||
did == PCI_DEVICE_ID_TTI_HPT302 ||
did == PCI_DEVICE_ID_TTI_HPT371) && rid > 1) ||
did == PCI_DEVICE_ID_TTI_HPT372N)
info->flags |= IS_3xxN;
info->revision = hpt_revision(dev);
if (info->revision >= 3)
hpt37x_clocking(hwif);
else
hpt366_clocking(hwif);
}
static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)
{
struct pci_dev *findev = NULL;
struct pci_dev *dev2;
if (PCI_FUNC(dev->devfn) & 1)
return -ENODEV;
while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
if ((findev->vendor == dev->vendor) &&
(findev->device == dev->device) &&
((findev->devfn - dev->devfn) == 1) &&
(PCI_FUNC(findev->devfn) & 1)) {
if (findev->irq != dev->irq) {
/* FIXME: we need a core pci_set_interrupt() */
findev->irq = dev->irq;
printk(KERN_WARNING "%s: pci-config space interrupt "
"fixed.\n", d->name);
}
return ide_setup_pci_devices(dev, findev, d);
pci_set_drvdata(dev, &hpt374);
if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
int ret;
pci_set_drvdata(dev2, &hpt374);
if (dev2->irq != dev->irq) {
/* FIXME: we need a core pci_set_interrupt() */
dev2->irq = dev->irq;
printk(KERN_WARNING "%s: PCI config space interrupt "
"fixed.\n", d->name);
}
ret = ide_setup_pci_devices(dev, dev2, d);
if (ret < 0)
pci_dev_put(dev2);
return ret;
}
return ide_setup_pci_device(dev, d);
}
static int __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d)
static int __devinit init_setup_hpt372n(struct pci_dev *dev, ide_pci_device_t *d)
{
pci_set_drvdata(dev, &hpt372n);
return ide_setup_pci_device(dev, d);
}
static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
{
u8 mcr1 = 0;
struct hpt_info *info;
u8 rev = 0, mcr1 = 0;
pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
if (rev > 1) {
d->name = "HPT371N";
info = &hpt371n;
} else
info = &hpt371;
/*
* HPT371 chips physically have only one channel, the secondary one,
......@@ -1453,59 +1469,94 @@ static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d)
*/
pci_read_config_byte(dev, 0x50, &mcr1);
if (mcr1 & 0x04)
pci_write_config_byte(dev, 0x50, (mcr1 & ~0x04));
pci_write_config_byte(dev, 0x50, mcr1 & ~0x04);
pci_set_drvdata(dev, info);
return ide_setup_pci_device(dev, d);
}
static int __devinit init_setup_hpt372a(struct pci_dev *dev, ide_pci_device_t *d)
{
struct hpt_info *info;
u8 rev = 0;
pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
if (rev > 1) {
d->name = "HPT372N";
info = &hpt372n;
} else
info = &hpt372a;
pci_set_drvdata(dev, info);
return ide_setup_pci_device(dev, d);
}
static int __devinit init_setup_hpt302(struct pci_dev *dev, ide_pci_device_t *d)
{
struct hpt_info *info;
u8 rev = 0;
pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
if (rev > 1) {
d->name = "HPT302N";
info = &hpt302n;
} else
info = &hpt302;
pci_set_drvdata(dev, info);
return ide_setup_pci_device(dev, d);
}
static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
{
struct pci_dev *findev = NULL;
u8 pin1 = 0, pin2 = 0;
unsigned int class_rev;
char *chipset_names[] = {"HPT366", "HPT366", "HPT368",
"HPT370", "HPT370A", "HPT372",
"HPT372N" };
struct pci_dev *dev2;
u8 rev = 0;
static char *chipset_names[] = { "HPT366", "HPT366", "HPT368",
"HPT370", "HPT370A", "HPT372",
"HPT372N" };
static struct hpt_info *info[] = { &hpt36x, &hpt36x, &hpt36x,
&hpt370, &hpt370a, &hpt372,
&hpt372n };
if (PCI_FUNC(dev->devfn) & 1)
return -ENODEV;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
if(dev->device == PCI_DEVICE_ID_TTI_HPT372N)
class_rev = 6;
if (rev > 6)
rev = 6;
if(class_rev <= 6)
d->name = chipset_names[class_rev];
switch(class_rev) {
case 6:
case 5:
case 4:
case 3:
goto init_single;
default:
break;
}
d->name = chipset_names[rev];
pci_set_drvdata(dev, info[rev]);
if (rev > 2)
goto init_single;
d->channels = 1;
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1);
while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
if ((findev->vendor == dev->vendor) &&
(findev->device == dev->device) &&
((findev->devfn - dev->devfn) == 1) &&
(PCI_FUNC(findev->devfn) & 1)) {
pci_read_config_byte(findev, PCI_INTERRUPT_PIN, &pin2);
if ((pin1 != pin2) && (dev->irq == findev->irq)) {
d->bootable = ON_BOARD;
printk("%s: onboard version of chipset, "
"pin1=%d pin2=%d\n", d->name,
pin1, pin2);
}
return ide_setup_pci_devices(dev, findev, d);
if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) {
u8 pin1 = 0, pin2 = 0;
int ret;
pci_set_drvdata(dev2, info[rev]);
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1);
pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
if (pin1 != pin2 && dev->irq == dev2->irq) {
d->bootable = ON_BOARD;
printk("%s: onboard version of chipset, pin1=%d pin2=%d\n",
d->name, pin1, pin2);
}
ret = ide_setup_pci_devices(dev, dev2, d);
if (ret < 0)
pci_dev_put(dev2);
return ret;
}
init_single:
return ide_setup_pci_device(dev, d);
......@@ -1516,64 +1567,68 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
.name = "HPT366",
.init_setup = init_setup_hpt366,
.init_chipset = init_chipset_hpt366,
.init_iops = init_iops_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.bootable = OFF_BOARD,
.extra = 240
},{ /* 1 */
.name = "HPT372A",
.init_setup = init_setup_hpt37x,
.init_setup = init_setup_hpt372a,
.init_chipset = init_chipset_hpt366,
.init_iops = init_iops_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.bootable = OFF_BOARD,
.extra = 240
},{ /* 2 */
.name = "HPT302",
.init_setup = init_setup_hpt37x,
.init_setup = init_setup_hpt302,
.init_chipset = init_chipset_hpt366,
.init_iops = init_iops_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.bootable = OFF_BOARD,
.extra = 240
},{ /* 3 */
.name = "HPT371",
.init_setup = init_setup_hpt371,
.init_chipset = init_chipset_hpt366,
.init_iops = init_iops_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.bootable = OFF_BOARD,
.extra = 240
},{ /* 4 */
.name = "HPT374",
.init_setup = init_setup_hpt374,
.init_chipset = init_chipset_hpt366,
.init_iops = init_iops_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.channels = 2, /* 4 */
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.bootable = OFF_BOARD,
.extra = 240
},{ /* 5 */
.name = "HPT372N",
.init_setup = init_setup_hpt37x,
.init_setup = init_setup_hpt372n,
.init_chipset = init_chipset_hpt366,
.init_iops = init_iops_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
.channels = 2, /* 4 */
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.bootable = OFF_BOARD,
.extra = 240
}
};
......
/*
* ITE 8213 IDE driver
*
* Copyright (C) 2006 Jack Lee
* Copyright (C) 2006 Alan Cox
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <asm/io.h>
/*
* it8213_ratemask - Compute available modes
* @drive: IDE drive
*
* Compute the available speeds for the devices on the interface. This
* is all modes to ATA133 clipped by drive cable setup.
*/
static u8 it8213_ratemask (ide_drive_t *drive)
{
u8 mode = 4;
if (!eighty_ninty_three(drive))
mode = min_t(u8, mode, 1);
return mode;
}
/**
* it8213_dma_2_pio - return the PIO mode matching DMA
* @xfer_rate: transfer speed
*
* Returns the nearest equivalent PIO timing for the PIO or DMA
* mode requested by the controller.
*/
static u8 it8213_dma_2_pio (u8 xfer_rate) {
switch(xfer_rate) {
case XFER_UDMA_6:
case XFER_UDMA_5:
case XFER_UDMA_4:
case XFER_UDMA_3:
case XFER_UDMA_2:
case XFER_UDMA_1:
case XFER_UDMA_0:
case XFER_MW_DMA_2:
case XFER_PIO_4:
return 4;
case XFER_MW_DMA_1:
case XFER_PIO_3:
return 3;
case XFER_SW_DMA_2:
case XFER_PIO_2:
return 2;
case XFER_MW_DMA_0:
case XFER_SW_DMA_1:
case XFER_SW_DMA_0:
case XFER_PIO_1:
case XFER_PIO_0:
case XFER_PIO_SLOW:
default:
return 0;
}
}
/*
* it8213_tuneproc - tune a drive
* @drive: drive to tune
* @pio: desired PIO mode
*
* Set the interface PIO mode.
*/
static void it8213_tuneproc (ide_drive_t *drive, u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
int is_slave = drive->dn & 1;
int master_port = 0x40;
int slave_port = 0x44;
unsigned long flags;
u16 master_data;
u8 slave_data;
static DEFINE_SPINLOCK(tune_lock);
int control = 0;
static const u8 timings[][2]= {
{ 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
{ 2, 3 }, };
pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
spin_lock_irqsave(&tune_lock, flags);
pci_read_config_word(dev, master_port, &master_data);
if (pio > 1)
control |= 1; /* Programmable timing on */
if (drive->media != ide_disk)
control |= 4; /* ATAPI */
if (pio > 2)
control |= 2; /* IORDY */
if (is_slave) {
master_data |= 0x4000;
master_data &= ~0x0070;
if (pio > 1)
master_data = master_data | (control << 4);
pci_read_config_byte(dev, slave_port, &slave_data);
slave_data = slave_data & 0xf0;
slave_data = slave_data | (timings[pio][0] << 2) | timings[pio][1];
} else {
master_data &= ~0x3307;
if (pio > 1)
master_data = master_data | control;
master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8);
}
pci_write_config_word(dev, master_port, master_data);
if (is_slave)
pci_write_config_byte(dev, slave_port, slave_data);
spin_unlock_irqrestore(&tune_lock, flags);
}
/**
* it8213_tune_chipset - set controller timings
* @drive: Drive to set up
* @xferspeed: speed we want to achieve
*
* Tune the ITE chipset for the desired mode. If we can't achieve
* the desired mode then tune for a lower one, but ultimately
* make the thing work.
*/
static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 maslave = 0x40;
u8 speed = ide_rate_filter(it8213_ratemask(drive), xferspeed);
int a_speed = 3 << (drive->dn * 4);
int u_flag = 1 << drive->dn;
int v_flag = 0x01 << drive->dn;
int w_flag = 0x10 << drive->dn;
int u_speed = 0;
u16 reg4042, reg4a;
u8 reg48, reg54, reg55;
pci_read_config_word(dev, maslave, &reg4042);
pci_read_config_byte(dev, 0x48, &reg48);
pci_read_config_word(dev, 0x4a, &reg4a);
pci_read_config_byte(dev, 0x54, &reg54);
pci_read_config_byte(dev, 0x55, &reg55);
switch(speed) {
case XFER_UDMA_6:
case XFER_UDMA_4:
case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
case XFER_UDMA_5:
case XFER_UDMA_3:
case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break;
case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break;
break;
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_SW_DMA_2:
break;
case XFER_PIO_4:
case XFER_PIO_3:
case XFER_PIO_2:
case XFER_PIO_1:
case XFER_PIO_0:
break;
default:
return -1;
}
if (speed >= XFER_UDMA_0) {
if (!(reg48 & u_flag))
pci_write_config_byte(dev, 0x48, reg48 | u_flag);
if (speed >= XFER_UDMA_5) {
pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag);
} else {
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
}
if ((reg4a & a_speed) != u_speed)
pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed);
if (speed > XFER_UDMA_2) {
if (!(reg54 & v_flag))
pci_write_config_byte(dev, 0x54, reg54 | v_flag);
} else
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
} else {
if (reg48 & u_flag)
pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
if (reg4a & a_speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
if (reg54 & v_flag)
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
if (reg55 & w_flag)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
}
it8213_tuneproc(drive, it8213_dma_2_pio(speed));
return ide_config_drive_speed(drive, speed);
}
/*
* config_chipset_for_dma - configure for DMA
* @drive: drive to configure
*
* Called by the IDE layer when it wants the timings set up.
*/
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, it8213_ratemask(drive));
if (!speed)
return 0;
it8213_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
/**
* it8213_configure_drive_for_dma - set up for DMA transfers
* @drive: drive we are going to set up
*
* Set up the drive for DMA, tune the controller and drive as
* required. If the drive isn't suitable for DMA or we hit
* other problems then we will drop down to PIO and set up
* PIO appropriately
*/
static int it8213_config_drive_for_dma (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
hwif->speedproc(drive, XFER_PIO_0
+ ide_get_best_pio_mode(drive, 255, 4, NULL));
return hwif->ide_dma_off_quietly(drive);
}
/**
* init_hwif_it8213 - set up hwif structs
* @hwif: interface to set up
*
* We do the basic set up of the interface structure. The IT8212
* requires several custom handlers so we override the default
* ide DMA handlers appropriately
*/
static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
{
u8 reg42h = 0, ata66 = 0;
hwif->speedproc = &it8213_tune_chipset;
hwif->tuneproc = &it8213_tuneproc;
hwif->autodma = 0;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
if (!hwif->dma_base)
return;
hwif->atapi_dma = 1;
hwif->ultra_mask = 0x7f;
hwif->mwdma_mask = 0x06;
hwif->swdma_mask = 0x04;
pci_read_config_byte(hwif->pci_dev, 0x42, &reg42h);
ata66 = (reg42h & 0x02) ? 0 : 1;
hwif->ide_dma_check = &it8213_config_drive_for_dma;
if (!(hwif->udma_four))
hwif->udma_four = ata66;
/*
* The BIOS often doesn't set up DMA on this controller
* so we always do it.
*/
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
hwif->drives[1].autodma = hwif->autodma;
}
#define DECLARE_ITE_DEV(name_str) \
{ \
.name = name_str, \
.init_hwif = init_hwif_it8213, \
.channels = 1, \
.autodma = AUTODMA, \
.enablebits = {{0x41,0x80,0x80}}, \
.bootable = ON_BOARD, \
}
static ide_pci_device_t it8213_chipsets[] __devinitdata = {
/* 0 */ DECLARE_ITE_DEV("IT8213"),
};
/**
* it8213_init_one - pci layer discovery entry
* @dev: PCI device
* @id: ident table entry
*
* Called by the PCI code when it finds an ITE8213 controller. As
* this device follows the standard interfaces we can use the
* standard helper functions to do almost all the work for us.
*/
static int __devinit it8213_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
ide_setup_pci_device(dev, &it8213_chipsets[id->driver_data]);
return 0;
}
static struct pci_device_id it8213_pci_tbl[] = {
{ PCI_VENDOR_ID_ITE, 0x8213, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, it8213_pci_tbl);
static struct pci_driver driver = {
.name = "ITE8213_IDE",
.id_table = it8213_pci_tbl,
.probe = it8213_init_one,
};
static int __init it8213_ide_init(void)
{
return ide_pci_register_driver(&driver);
}
module_init(it8213_ide_init);
MODULE_AUTHOR("Jack Lee, Alan Cox");
MODULE_DESCRIPTION("PCI driver module for the ITE 8213");
MODULE_LICENSE("GPL");
......@@ -92,26 +92,6 @@ static u8 pdcnew_ratemask(ide_drive_t *drive)
return mode;
}
static int check_in_drive_lists(ide_drive_t *drive, const char **list)
{
struct hd_driveid *id = drive->id;
if (pdc_quirk_drives == list) {
while (*list) {
if (strstr(id->model, *list++)) {
return 2;
}
}
} else {
while (*list) {
if (!strcmp(*list++,id->model)) {
return 1;
}
}
}
return 0;
}
/**
* get_indexed_reg - Get indexed register
* @hwif: for the port address
......@@ -249,13 +229,6 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed)
return err;
}
/* 0 1 2 3 4 5 6 7 8
* 960, 480, 390, 300, 240, 180, 120, 90, 60
* 180, 150, 120, 90, 60
* DMA_Speed
* 180, 120, 90, 90, 90, 60, 30
* 11, 5, 4, 3, 2, 1, 0
*/
static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio)
{
pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
......@@ -313,12 +286,10 @@ static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
drive->init_speed = 0;
if (id && (id->capability & 1) && drive->autodma) {
if ((id->capability & 1) && drive->autodma) {
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
goto fast_ata_pio;
......@@ -333,21 +304,12 @@ static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
static int pdcnew_quirkproc(ide_drive_t *drive)
{
return check_in_drive_lists(drive, pdc_quirk_drives);
}
const char **list, *model = drive->id->model;
static int pdcnew_ide_dma_lostirq(ide_drive_t *drive)
{
if (HWIF(drive)->resetproc != NULL)
HWIF(drive)->resetproc(drive);
return __ide_dma_lostirq(drive);
}
static int pdcnew_ide_dma_timeout(ide_drive_t *drive)
{
if (HWIF(drive)->resetproc != NULL)
HWIF(drive)->resetproc(drive);
return __ide_dma_timeout(drive);
for (list = pdc_quirk_drives; *list != NULL; list++)
if (strstr(model, *list) != NULL)
return 2;
return 0;
}
static void pdcnew_reset(ide_drive_t *drive)
......@@ -599,8 +561,6 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
hwif->err_stops_fifo = 1;
hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate;
hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq;
hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout;
if (!hwif->udma_four)
hwif->udma_four = pdcnew_cable_detect(hwif) ? 0 : 1;
......
......@@ -123,26 +123,6 @@ static u8 pdc202xx_ratemask (ide_drive_t *drive)
return mode;
}
static int check_in_drive_lists (ide_drive_t *drive, const char **list)
{
struct hd_driveid *id = drive->id;
if (pdc_quirk_drives == list) {
while (*list) {
if (strstr(id->model, *list++)) {
return 2;
}
}
} else {
while (*list) {
if (!strcmp(*list++,id->model)) {
return 1;
}
}
}
return 0;
}
static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
{
ide_hwif_t *hwif = HWIF(drive);
......@@ -377,7 +357,12 @@ static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
static int pdc202xx_quirkproc (ide_drive_t *drive)
{
return ((int) check_in_drive_lists(drive, pdc_quirk_drives));
const char **list, *model = drive->id->model;
for (list = pdc_quirk_drives; *list != NULL; list++)
if (strstr(model, *list) != NULL)
return 2;
return 0;
}
static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
......
/*
* linux/drivers/ide/pci/piix.c Version 0.45 May 12, 2006
* linux/drivers/ide/pci/piix.c Version 0.46 December 3, 2006
*
* Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
......@@ -163,7 +163,7 @@ static u8 piix_ratemask (ide_drive_t *drive)
* if the drive cannot see an 80pin cable.
*/
if (!eighty_ninty_three(drive))
mode = min(mode, (u8)1);
mode = min_t(u8, mode, 1);
return mode;
}
......@@ -216,7 +216,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
int is_slave = (&hwif->drives[1] == drive);
int is_slave = drive->dn & 1;
int master_port = hwif->channel ? 0x42 : 0x40;
int slave_port = 0x44;
unsigned long flags;
......@@ -225,7 +225,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
static DEFINE_SPINLOCK(tune_lock);
int control = 0;
/* ISP RTC */
/* ISP RTC */
static const u8 timings[][2]= {
{ 0, 0 },
{ 0, 0 },
......@@ -233,7 +233,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
{ 2, 1 },
{ 2, 3 }, };
pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
/*
* Master vs slave is synchronized above us but the slave register is
......@@ -243,25 +243,24 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
spin_lock_irqsave(&tune_lock, flags);
pci_read_config_word(dev, master_port, &master_data);
if (pio >= 2)
if (pio > 1)
control |= 1; /* Programmable timing on */
if (drive->media == ide_disk)
control |= 4; /* Prefetch, post write */
if (pio >= 3)
if (pio > 2)
control |= 2; /* IORDY */
if (is_slave) {
master_data = master_data | 0x4000;
master_data |= 0x4000;
master_data &= ~0x0070;
if (pio > 1) {
/* enable PPE, IE and TIME */
master_data = master_data | (control << 4);
} else {
master_data &= ~0x0070;
}
pci_read_config_byte(dev, slave_port, &slave_data);
slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0);
slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0));
} else {
master_data = master_data & 0xccf8;
master_data &= ~0x3307;
if (pio > 1) {
/* enable PPE, IE and TIME */
master_data = master_data | control;
......@@ -539,13 +538,19 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = {
/* 0 */ DECLARE_PIIX_DEV("PIIXa"),
/* 1 */ DECLARE_PIIX_DEV("PIIXb"),
{ /* 2 */
/* 2 */
{ /*
* MPIIX actually has only a single IDE channel mapped to
* the primary or secondary ports depending on the value
* of the bit 14 of the IDETIM register at offset 0x6c
*/
.name = "MPIIX",
.init_hwif = init_hwif_piix,
.channels = 2,
.autodma = NODMA,
.enablebits = {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}},
.enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
.bootable = ON_BOARD,
.flags = IDEPCI_FLAG_ISA_PORTS
},
/* 3 */ DECLARE_PIIX_DEV("PIIX3"),
......
/*
* linux/drivers/ide/pci/slc90e66.c Version 0.12 May 12, 2006
* linux/drivers/ide/pci/slc90e66.c Version 0.13 December 30, 2006
*
* Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2006 MontaVista Software, Inc. <source@mvista.com>
......@@ -26,7 +26,7 @@ static u8 slc90e66_ratemask (ide_drive_t *drive)
u8 mode = 2;
if (!eighty_ninty_three(drive))
mode = min(mode, (u8)1);
mode = min_t(u8, mode, 1);
return mode;
}
......@@ -65,36 +65,47 @@ static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
int is_slave = (&hwif->drives[1] == drive);
int is_slave = drive->dn & 1;
int master_port = hwif->channel ? 0x42 : 0x40;
int slave_port = 0x44;
unsigned long flags;
u16 master_data;
u8 slave_data;
/* ISP RTC */
int control = 0;
/* ISP RTC */
static const u8 timings[][2]= {
{ 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
{ 2, 3 }, };
{ 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
{ 2, 3 }, };
pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
spin_lock_irqsave(&ide_lock, flags);
pci_read_config_word(dev, master_port, &master_data);
if (pio > 1)
control |= 1; /* Programmable timing on */
if (drive->media == ide_disk)
control |= 4; /* Prefetch, post write */
if (pio > 2)
control |= 2; /* IORDY */
if (is_slave) {
master_data = master_data | 0x4000;
if (pio > 1)
master_data |= 0x4000;
master_data &= ~0x0070;
if (pio > 1) {
/* enable PPE, IE and TIME */
master_data = master_data | 0x0070;
master_data = master_data | (control << 4);
}
pci_read_config_byte(dev, slave_port, &slave_data);
slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0);
slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0));
} else {
master_data = master_data & 0xccf8;
if (pio > 1)
master_data &= ~0x3307;
if (pio > 1) {
/* enable PPE, IE and TIME */
master_data = master_data | 0x0007;
master_data = master_data | control;
}
master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8);
}
pci_write_config_word(dev, master_port, master_data);
......@@ -173,7 +184,7 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if (id && (id->capability & 1) && drive->autodma) {
if ((id->capability & 1) && drive->autodma) {
if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
return hwif->ide_dma_on(drive);
......@@ -201,7 +212,7 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
hwif->irq = hwif->channel ? 15 : 14;
hwif->speedproc = &slc90e66_tune_chipset;
hwif->tuneproc = &slc90e66_tune_drive;
hwif->tuneproc = &slc90e66_tune_drive;
pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
......@@ -213,14 +224,16 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
hwif->atapi_dma = 1;
hwif->ultra_mask = 0x1f;
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
hwif->mwdma_mask = 0x06;
hwif->swdma_mask = 0x04;
if (!(hwif->udma_four))
if (!hwif->udma_four) {
/* bit[0(1)]: 0:80, 1:40 */
hwif->udma_four = (reg47 & mask) ? 0 : 1;
}
hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate;
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->autodma;
......
/*
* drivers/ide/pci/tc86c001.c Version 1.00 Dec 12, 2006
*
* Copyright (C) 2002 Toshiba Corporation
* Copyright (C) 2005-2006 MontaVista Software, Inc. <source@mvista.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/ide.h>
static inline u8 tc86c001_ratemask(ide_drive_t *drive)
{
return eighty_ninty_three(drive) ? 2 : 1;
}
static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00);
u16 mode, scr = hwif->INW(scr_port);
speed = ide_rate_filter(tc86c001_ratemask(drive), speed);
switch (speed) {
case XFER_UDMA_4: mode = 0x00c0; break;
case XFER_UDMA_3: mode = 0x00b0; break;
case XFER_UDMA_2: mode = 0x00a0; break;
case XFER_UDMA_1: mode = 0x0090; break;
case XFER_UDMA_0: mode = 0x0080; break;
case XFER_MW_DMA_2: mode = 0x0070; break;
case XFER_MW_DMA_1: mode = 0x0060; break;
case XFER_MW_DMA_0: mode = 0x0050; break;
case XFER_PIO_4: mode = 0x0400; break;
case XFER_PIO_3: mode = 0x0300; break;
case XFER_PIO_2: mode = 0x0200; break;
case XFER_PIO_1: mode = 0x0100; break;
case XFER_PIO_0:
default: mode = 0x0000; break;
}
scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
scr |= mode;
hwif->OUTW(scr, scr_port);
return ide_config_drive_speed(drive, speed);
}
static void tc86c001_tune_drive(ide_drive_t *drive, u8 pio)
{
pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
(void) tc86c001_tune_chipset(drive, XFER_PIO_0 + pio);
}
/*
* HACKITY HACK
*
* This is a workaround for the limitation 5 of the TC86C001 IDE controller:
* if a DMA transfer terminates prematurely, the controller leaves the device's
* interrupt request (INTRQ) pending and does not generate a PCI interrupt (or
* set the interrupt bit in the DMA status register), thus no PCI interrupt
* will occur until a DMA transfer has been successfully completed.
*
* We work around this by initiating dummy, zero-length DMA transfer on
* a DMA timeout expiration. I found no better way to do this with the current
* IDE core than to temporarily replace a higher level driver's timer expiry
* handler with our own backing up to that handler in case our recovery fails.
*/
static int tc86c001_timer_expiry(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
ide_expiry_t *expiry = ide_get_hwifdata(hwif);
ide_hwgroup_t *hwgroup = HWGROUP(drive);
u8 dma_stat = hwif->INB(hwif->dma_status);
/* Restore a higher level driver's expiry handler first. */
hwgroup->expiry = expiry;
if ((dma_stat & 5) == 1) { /* DMA active and no interrupt */
unsigned long sc_base = hwif->config_data;
unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04);
u8 dma_cmd = hwif->INB(hwif->dma_command);
printk(KERN_WARNING "%s: DMA interrupt possibly stuck, "
"attempting recovery...\n", drive->name);
/* Stop DMA */
hwif->OUTB(dma_cmd & ~0x01, hwif->dma_command);
/* Setup the dummy DMA transfer */
hwif->OUTW(0, sc_base + 0x0a); /* Sector Count */
hwif->OUTW(0, twcr_port); /* Transfer Word Count 1 or 2 */
/* Start the dummy DMA transfer */
hwif->OUTB(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */
hwif->OUTB(0x01, hwif->dma_command); /* set START_STOPBM */
/*
* If an interrupt was pending, it should come thru shortly.
* If not, a higher level driver's expiry handler should
* eventually cause some kind of recovery from the DMA stall.
*/
return WAIT_MIN_SLEEP;
}
/* Chain to the restored expiry handler if DMA wasn't active. */
if (likely(expiry != NULL))
return expiry(drive);
/* If there was no handler, "emulate" that for ide_timer_expiry()... */
return -1;
}
static void tc86c001_dma_start(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
ide_hwgroup_t *hwgroup = HWGROUP(drive);
unsigned long sc_base = hwif->config_data;
unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04);
unsigned long nsectors = hwgroup->rq->nr_sectors;
/*
* We have to manually load the sector count and size into
* the appropriate system control registers for DMA to work
* with LBA48 and ATAPI devices...
*/
hwif->OUTW(nsectors, sc_base + 0x0a); /* Sector Count */
hwif->OUTW(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */
/* Install our timeout expiry hook, saving the current handler... */
ide_set_hwifdata(hwif, hwgroup->expiry);
hwgroup->expiry = &tc86c001_timer_expiry;
ide_dma_start(drive);
}
static int tc86c001_busproc(ide_drive_t *drive, int state)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long sc_base = hwif->config_data;
u16 scr1;
/* System Control 1 Register bit 11 (ATA Hard Reset) read */
scr1 = hwif->INW(sc_base + 0x00);
switch (state) {
case BUSSTATE_ON:
if (!(scr1 & 0x0800))
return 0;
scr1 &= ~0x0800;
hwif->drives[0].failures = hwif->drives[1].failures = 0;
break;
case BUSSTATE_OFF:
if (scr1 & 0x0800)
return 0;
scr1 |= 0x0800;
hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
break;
default:
return -EINVAL;
}
/* System Control 1 Register bit 11 (ATA Hard Reset) write */
hwif->OUTW(scr1, sc_base + 0x00);
return 0;
}
static int config_chipset_for_dma(ide_drive_t *drive)
{
u8 speed = ide_dma_speed(drive, tc86c001_ratemask(drive));
if (!speed)
return 0;
(void) tc86c001_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct hd_driveid *id = drive->id;
if ((id->capability & 1) && drive->autodma) {
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
goto fast_ata_pio;
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
tc86c001_tune_drive(drive, 255);
return hwif->ide_dma_off_quietly(drive);
}
/* IORDY not supported */
return 0;
}
static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
{
unsigned long sc_base = pci_resource_start(hwif->pci_dev, 5);
u16 scr1 = hwif->INW(sc_base + 0x00);;
/* System Control 1 Register bit 15 (Soft Reset) set */
hwif->OUTW(scr1 | 0x8000, sc_base + 0x00);
/* System Control 1 Register bit 14 (FIFO Reset) set */
hwif->OUTW(scr1 | 0x4000, sc_base + 0x00);
/* System Control 1 Register: reset clear */
hwif->OUTW(scr1 & ~0xc000, sc_base + 0x00);
/* Store the system control register base for convenience... */
hwif->config_data = sc_base;
hwif->tuneproc = &tc86c001_tune_drive;
hwif->speedproc = &tc86c001_tune_chipset;
hwif->busproc = &tc86c001_busproc;
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
if (!hwif->dma_base)
return;
/*
* Sector Count Control Register bits 0 and 1 set:
* software sets Sector Count Register for master and slave device
*/
hwif->OUTW(0x0003, sc_base + 0x0c);
/* Sector Count Register limit */
hwif->rqsize = 0xffff;
hwif->atapi_dma = 1;
hwif->ultra_mask = 0x1f;
hwif->mwdma_mask = 0x07;
hwif->ide_dma_check = &tc86c001_config_drive_xfer_rate;
hwif->dma_start = &tc86c001_dma_start;
if (!hwif->udma_four) {
/*
* System Control 1 Register bit 13 (PDIAGN):
* 0=80-pin cable, 1=40-pin cable
*/
scr1 = hwif->INW(sc_base + 0x00);
hwif->udma_four = (scr1 & 0x2000) ? 0 : 1;
}
if (!noautodma)
hwif->autodma = 1;
hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;
}
static unsigned int __devinit init_chipset_tc86c001(struct pci_dev *dev,
const char *name)
{
int err = pci_request_region(dev, 5, name);
if (err)
printk(KERN_ERR "%s: system control regs already in use", name);
return err;
}
static ide_pci_device_t tc86c001_chipset __devinitdata = {
.name = "TC86C001",
.init_chipset = init_chipset_tc86c001,
.init_hwif = init_hwif_tc86c001,
.channels = 1,
.autodma = AUTODMA,
.bootable = OFF_BOARD
};
static int __devinit tc86c001_init_one(struct pci_dev *dev,
const struct pci_device_id *id)
{
return ide_setup_pci_device(dev, &tc86c001_chipset);
}
static struct pci_device_id tc86c001_pci_tbl[] = {
{ PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0, }
};
MODULE_DEVICE_TABLE(pci, tc86c001_pci_tbl);
static struct pci_driver driver = {
.name = "TC86C001",
.id_table = tc86c001_pci_tbl,
.probe = tc86c001_init_one
};
static int __init tc86c001_ide_init(void)
{
return ide_pci_register_driver(&driver);
}
module_init(tc86c001_ide_init);
MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
MODULE_DESCRIPTION("PCI driver module for TC86C001 IDE");
MODULE_LICENSE("GPL");
......@@ -1460,6 +1460,24 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2609, quirk_intel_pcie_pm);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm);
/*
* Toshiba TC86C001 IDE controller reports the standard 8-byte BAR0 size
* but the PIO transfers won't work if BAR0 falls at the odd 8 bytes.
* Re-allocate the region if needed...
*/
static void __init quirk_tc86c001_ide(struct pci_dev *dev)
{
struct resource *r = &dev->resource[0];
if (r->start & 0x8) {
r->start = 0;
r->end = 0xf;
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2,
PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE,
quirk_tc86c001_ide);
static void __devinit quirk_netmos(struct pci_dev *dev)
{
unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4;
......
......@@ -18,6 +18,9 @@
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/completion.h>
#ifdef CONFIG_BLK_DEV_IDEACPI
#include <acpi/acpi.h>
#endif
#include <asm/byteorder.h>
#include <asm/system.h>
#include <asm/io.h>
......@@ -541,6 +544,11 @@ typedef enum {
struct ide_driver_s;
struct ide_settings_s;
#ifdef CONFIG_BLK_DEV_IDEACPI
struct ide_acpi_drive_link;
struct ide_acpi_hwif_link;
#endif
typedef struct ide_drive_s {
char name[4]; /* drive name, such as "hda" */
char driver_req[10]; /* requests specific driver */
......@@ -637,6 +645,9 @@ typedef struct ide_drive_s {
int lun; /* logical unit */
int crc_count; /* crc counter to reduce drive speed */
#ifdef CONFIG_BLK_DEV_IDEACPI
struct ide_acpi_drive_link *acpidata;
#endif
struct list_head list;
struct device gendev;
struct completion gendev_rel_comp; /* to deal with device release() */
......@@ -804,6 +815,10 @@ typedef struct hwif_s {
void *hwif_data; /* extra hwif data */
unsigned dma;
#ifdef CONFIG_BLK_DEV_IDEACPI
struct ide_acpi_hwif_link *acpidata;
#endif
} ____cacheline_internodealigned_in_smp ide_hwif_t;
/*
......@@ -1298,6 +1313,18 @@ static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
static inline void ide_release_dma(ide_hwif_t *drive) {;}
#endif
#ifdef CONFIG_BLK_DEV_IDEACPI
extern int ide_acpi_exec_tfs(ide_drive_t *drive);
extern void ide_acpi_get_timing(ide_hwif_t *hwif);
extern void ide_acpi_push_timing(ide_hwif_t *hwif);
extern void ide_acpi_init(ide_hwif_t *hwif);
#else
static inline int ide_acpi_exec_tfs(ide_drive_t *drive) { return 0; }
static inline void ide_acpi_get_timing(ide_hwif_t *hwif) { ; }
static inline void ide_acpi_push_timing(ide_hwif_t *hwif) { ; }
static inline void ide_acpi_init(ide_hwif_t *hwif) { ; }
#endif
extern int ide_hwif_request_regions(ide_hwif_t *hwif);
extern void ide_hwif_release_regions(ide_hwif_t* hwif);
extern void ide_unregister (unsigned int index);
......
......@@ -1454,6 +1454,7 @@
#define PCI_VENDOR_ID_TOSHIBA_2 0x102f
#define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030
#define PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE 0x0105
#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108
#define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3
......
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