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: (30 commits) ide: make ide_hwif_t.ide_dma_host_on void (v2) ide: make ide_hwif_t.ide_dma_{host_off,off_quietly} void (v2) ide: add ide_set_dma() helper (v2) sgiioc4: fix sgiioc4_ide_dma_check() to enable/disable DMA properly ide: disable DMA in ->ide_dma_check for "no IORDY" case (v2) ide: convert ide_hwif_t.mmio into flag (v2) ide: use PIO/MMIO operations directly where possible (v2) ide: add ide_use_fast_pio() helper (v3) ide: unexport ide_set_xfer_rate() (v2) ide: remove ide_drive_t.usage ide: remove ide_pci_device_t tables with only one entry ide: remove write-only ide_hwif_t.no_dsc flag ide: remove write-only ide_pio_data_t.blacklisted sis5513: sis5513_config_xfer_rate() cleanup piix: cleanup svwks: small cleanup cs5530: small cleanup hpt366: remove redundant check from init_dma_hpt366() trm290: remove redundant CONFIG_BLK_DEV_IDEDMA #ifdef-s au1xxx-ide: remove dead code ...
This commit is contained in:
commit
dd397a6d1a
@ -797,6 +797,14 @@ config BLK_DEV_IDEDMA_PMAC
|
||||
to transfer data to and from memory. Saying Y is safe and improves
|
||||
performance.
|
||||
|
||||
config BLK_DEV_IDE_CELLEB
|
||||
bool "Toshiba's Cell Reference Set IDE support"
|
||||
depends on PPC_CELLEB
|
||||
help
|
||||
This driver provides support for the built-in IDE controller on
|
||||
Toshiba Cell Reference Board.
|
||||
If unsure, say Y.
|
||||
|
||||
config BLK_DEV_IDE_SWARM
|
||||
tristate "IDE for Sibyte evaluation boards"
|
||||
depends on SIBYTE_SB1xxx_SOC
|
||||
|
@ -37,6 +37,7 @@ ide-core-$(CONFIG_BLK_DEV_Q40IDE) += legacy/q40ide.o
|
||||
# built-in only drivers from ppc/
|
||||
ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ppc/mpc8xx.o
|
||||
ide-core-$(CONFIG_BLK_DEV_IDE_PMAC) += ppc/pmac.o
|
||||
ide-core-$(CONFIG_BLK_DEV_IDE_CELLEB) += ppc/scc_pata.o
|
||||
|
||||
# built-in only drivers from h8300/
|
||||
ide-core-$(CONFIG_H8300) += h8300/ide-h8300.o
|
||||
|
@ -307,26 +307,24 @@ static int icside_set_speed(ide_drive_t *drive, u8 xfer_mode)
|
||||
return on;
|
||||
}
|
||||
|
||||
static int icside_dma_host_off(ide_drive_t *drive)
|
||||
static void icside_dma_host_off(ide_drive_t *drive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int icside_dma_off_quietly(ide_drive_t *drive)
|
||||
static void icside_dma_off_quietly(ide_drive_t *drive)
|
||||
{
|
||||
drive->using_dma = 0;
|
||||
return icside_dma_host_off(drive);
|
||||
}
|
||||
|
||||
static int icside_dma_host_on(ide_drive_t *drive)
|
||||
static void icside_dma_host_on(ide_drive_t *drive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int icside_dma_on(ide_drive_t *drive)
|
||||
{
|
||||
drive->using_dma = 1;
|
||||
return icside_dma_host_on(drive);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int icside_dma_check(ide_drive_t *drive)
|
||||
@ -365,10 +363,7 @@ static int icside_dma_check(ide_drive_t *drive)
|
||||
out:
|
||||
on = icside_set_speed(drive, xfer_mode);
|
||||
|
||||
if (on)
|
||||
return icside_dma_on(drive);
|
||||
else
|
||||
return icside_dma_off_quietly(drive);
|
||||
return on ? 0 : -1;
|
||||
}
|
||||
|
||||
static int icside_dma_end(ide_drive_t *drive)
|
||||
@ -497,9 +492,9 @@ static void icside_dma_init(ide_hwif_t *hwif)
|
||||
hwif->autodma = autodma;
|
||||
|
||||
hwif->ide_dma_check = icside_dma_check;
|
||||
hwif->ide_dma_host_off = icside_dma_host_off;
|
||||
hwif->ide_dma_off_quietly = icside_dma_off_quietly;
|
||||
hwif->ide_dma_host_on = icside_dma_host_on;
|
||||
hwif->dma_host_off = icside_dma_host_off;
|
||||
hwif->dma_off_quietly = icside_dma_off_quietly;
|
||||
hwif->dma_host_on = icside_dma_host_on;
|
||||
hwif->ide_dma_on = icside_dma_on;
|
||||
hwif->dma_setup = icside_dma_setup;
|
||||
hwif->dma_exec_cmd = icside_dma_exec_cmd;
|
||||
@ -556,7 +551,7 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e
|
||||
* Ensure we're using MMIO
|
||||
*/
|
||||
default_hwif_mmiops(hwif);
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
|
||||
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
|
||||
hwif->hw.io_ports[i] = port;
|
||||
|
@ -46,7 +46,7 @@ rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int
|
||||
hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
|
||||
hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
|
||||
hwif->hw.irq = hwif->irq = irq;
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
default_hwif_mmiops(hwif);
|
||||
|
||||
return hwif;
|
||||
|
@ -682,9 +682,12 @@ static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int);
|
||||
static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
|
||||
static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
|
||||
static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
|
||||
static int cris_dma_off (ide_drive_t *drive);
|
||||
static int cris_dma_on (ide_drive_t *drive);
|
||||
|
||||
static void cris_dma_off(ide_drive_t *drive)
|
||||
{
|
||||
}
|
||||
|
||||
static void tune_cris_ide(ide_drive_t *drive, u8 pio)
|
||||
{
|
||||
int setup, strobe, hold;
|
||||
@ -795,7 +798,7 @@ init_e100_ide (void)
|
||||
0, 0, cris_ide_ack_intr,
|
||||
ide_default_irq(0));
|
||||
ide_register_hw(&hw, &hwif);
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
hwif->chipset = ide_etrax100;
|
||||
hwif->tuneproc = &tune_cris_ide;
|
||||
hwif->speedproc = &speed_cris_ide;
|
||||
@ -814,13 +817,16 @@ init_e100_ide (void)
|
||||
hwif->OUTBSYNC = &cris_ide_outbsync;
|
||||
hwif->INB = &cris_ide_inb;
|
||||
hwif->INW = &cris_ide_inw;
|
||||
hwif->ide_dma_host_off = &cris_dma_off;
|
||||
hwif->ide_dma_host_on = &cris_dma_on;
|
||||
hwif->ide_dma_off_quietly = &cris_dma_off;
|
||||
hwif->dma_host_off = &cris_dma_off;
|
||||
hwif->dma_host_on = &cris_dma_on;
|
||||
hwif->dma_off_quietly = &cris_dma_off;
|
||||
hwif->udma_four = 0;
|
||||
hwif->ultra_mask = cris_ultra_mask;
|
||||
hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
|
||||
hwif->swdma_mask = 0x07; /* Singleword DMA 0-2 */
|
||||
hwif->autodma = 1;
|
||||
hwif->drives[0].autodma = 1;
|
||||
hwif->drives[1].autodma = 1;
|
||||
}
|
||||
|
||||
/* Reset pulse */
|
||||
@ -835,11 +841,6 @@ init_e100_ide (void)
|
||||
cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
|
||||
}
|
||||
|
||||
static int cris_dma_off (ide_drive_t *drive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cris_dma_on (ide_drive_t *drive)
|
||||
{
|
||||
return 0;
|
||||
@ -1045,17 +1046,10 @@ static ide_startstop_t cris_dma_intr (ide_drive_t *drive)
|
||||
|
||||
static int cris_dma_check(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = drive->hwif;
|
||||
struct hd_driveid* id = drive->id;
|
||||
if (ide_use_dma(drive) && cris_config_drive_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (id && (id->capability & 1)) {
|
||||
if (ide_use_dma(drive)) {
|
||||
if (cris_config_drive_for_dma(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
}
|
||||
}
|
||||
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cris_dma_end(ide_drive_t *drive)
|
||||
|
@ -76,13 +76,11 @@ static inline void hwif_setup(ide_hwif_t *hwif)
|
||||
{
|
||||
default_hwif_iops(hwif);
|
||||
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
hwif->OUTW = mm_outw;
|
||||
hwif->OUTSW = mm_outsw;
|
||||
hwif->INW = mm_inw;
|
||||
hwif->INSW = mm_insw;
|
||||
hwif->OUTL = NULL;
|
||||
hwif->INL = NULL;
|
||||
hwif->OUTSL = NULL;
|
||||
hwif->INSL = NULL;
|
||||
}
|
||||
|
@ -687,15 +687,8 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 sta
|
||||
static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
|
||||
{
|
||||
struct request *rq = HWGROUP(drive)->rq;
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
int stat, err, sense_key;
|
||||
|
||||
/* We may have bogus DMA interrupts in PIO state here */
|
||||
if (HWIF(drive)->dma_status && hwif->atapi_irq_bogon) {
|
||||
stat = hwif->INB(hwif->dma_status);
|
||||
/* Should we force the bit as well ? */
|
||||
hwif->OUTB(stat, hwif->dma_status);
|
||||
}
|
||||
/* Check for errors. */
|
||||
stat = HWIF(drive)->INB(IDE_STATUS_REG);
|
||||
if (stat_ret)
|
||||
@ -930,6 +923,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
|
||||
HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
|
||||
|
||||
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
|
||||
/* waiting for CDB interrupt, not DMA yet. */
|
||||
if (info->dma)
|
||||
drive->waiting_for_dma = 0;
|
||||
|
||||
/* packet command */
|
||||
ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
|
||||
return ide_started;
|
||||
@ -972,6 +969,10 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
|
||||
/* Check for errors. */
|
||||
if (cdrom_decode_status(drive, DRQ_STAT, NULL))
|
||||
return ide_stopped;
|
||||
|
||||
/* Ok, next interrupt will be DMA interrupt. */
|
||||
if (info->dma)
|
||||
drive->waiting_for_dma = 1;
|
||||
} else {
|
||||
/* Otherwise, we must wait for DRQ to get set. */
|
||||
if (ide_wait_stat(&startstop, drive, DRQ_STAT,
|
||||
@ -1103,7 +1104,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
|
||||
if (dma) {
|
||||
info->dma = 0;
|
||||
if ((dma_error = HWIF(drive)->ide_dma_end(drive)))
|
||||
__ide_dma_off(drive);
|
||||
ide_dma_off(drive);
|
||||
}
|
||||
|
||||
if (cdrom_decode_status(drive, 0, &stat))
|
||||
@ -1699,7 +1700,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
|
||||
if (dma) {
|
||||
if (dma_error) {
|
||||
printk(KERN_ERR "ide-cd: dma error\n");
|
||||
__ide_dma_off(drive);
|
||||
ide_dma_off(drive);
|
||||
return ide_error(drive, "dma error", stat);
|
||||
}
|
||||
|
||||
@ -1825,7 +1826,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
|
||||
info->dma = 0;
|
||||
if ((dma_error = HWIF(drive)->ide_dma_end(drive))) {
|
||||
printk(KERN_ERR "ide-cd: write dma error\n");
|
||||
__ide_dma_off(drive);
|
||||
ide_dma_off(drive);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3254,14 +3255,6 @@ int ide_cdrom_setup (ide_drive_t *drive)
|
||||
if (drive->autotune == IDE_TUNE_DEFAULT ||
|
||||
drive->autotune == IDE_TUNE_AUTO)
|
||||
drive->dsc_overlap = (drive->next != drive);
|
||||
#if 0
|
||||
drive->dsc_overlap = (HWIF(drive)->no_dsc) ? 0 : 1;
|
||||
if (HWIF(drive)->no_dsc) {
|
||||
printk(KERN_INFO "ide-cd: %s: disabling DSC overlap\n",
|
||||
drive->name);
|
||||
drive->dsc_overlap = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ide_cdrom_register(drive, nslots)) {
|
||||
printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
|
||||
@ -3360,21 +3353,16 @@ static int idecd_open(struct inode * inode, struct file * file)
|
||||
{
|
||||
struct gendisk *disk = inode->i_bdev->bd_disk;
|
||||
struct cdrom_info *info;
|
||||
ide_drive_t *drive;
|
||||
int rc = -ENOMEM;
|
||||
|
||||
if (!(info = ide_cd_get(disk)))
|
||||
return -ENXIO;
|
||||
|
||||
drive = info->drive;
|
||||
|
||||
drive->usage++;
|
||||
|
||||
if (!info->buffer)
|
||||
info->buffer = kmalloc(SECTOR_BUFFER_SIZE,
|
||||
GFP_KERNEL|__GFP_REPEAT);
|
||||
if (!info->buffer || (rc = cdrom_open(&info->devinfo, inode, file)))
|
||||
drive->usage--;
|
||||
info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
|
||||
|
||||
if (info->buffer)
|
||||
rc = cdrom_open(&info->devinfo, inode, file);
|
||||
|
||||
if (rc < 0)
|
||||
ide_cd_put(info);
|
||||
@ -3386,10 +3374,8 @@ static int idecd_release(struct inode * inode, struct file * file)
|
||||
{
|
||||
struct gendisk *disk = inode->i_bdev->bd_disk;
|
||||
struct cdrom_info *info = ide_cd_g(disk);
|
||||
ide_drive_t *drive = info->drive;
|
||||
|
||||
cdrom_release (&info->devinfo, file);
|
||||
drive->usage--;
|
||||
|
||||
ide_cd_put(info);
|
||||
|
||||
|
@ -77,6 +77,7 @@ struct ide_disk_obj {
|
||||
ide_driver_t *driver;
|
||||
struct gendisk *disk;
|
||||
struct kref kref;
|
||||
unsigned int openers; /* protected by BKL for now */
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(idedisk_ref_mutex);
|
||||
@ -1081,8 +1082,9 @@ static int idedisk_open(struct inode *inode, struct file *filp)
|
||||
|
||||
drive = idkp->drive;
|
||||
|
||||
drive->usage++;
|
||||
if (drive->removable && drive->usage == 1) {
|
||||
idkp->openers++;
|
||||
|
||||
if (drive->removable && idkp->openers == 1) {
|
||||
ide_task_t args;
|
||||
memset(&args, 0, sizeof(ide_task_t));
|
||||
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK;
|
||||
@ -1106,9 +1108,10 @@ static int idedisk_release(struct inode *inode, struct file *filp)
|
||||
struct ide_disk_obj *idkp = ide_disk_g(disk);
|
||||
ide_drive_t *drive = idkp->drive;
|
||||
|
||||
if (drive->usage == 1)
|
||||
if (idkp->openers == 1)
|
||||
ide_cacheflush_p(drive);
|
||||
if (drive->removable && drive->usage == 1) {
|
||||
|
||||
if (drive->removable && idkp->openers == 1) {
|
||||
ide_task_t args;
|
||||
memset(&args, 0, sizeof(ide_task_t));
|
||||
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORUNLOCK;
|
||||
@ -1117,7 +1120,8 @@ static int idedisk_release(struct inode *inode, struct file *filp)
|
||||
if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
|
||||
drive->doorlocking = 0;
|
||||
}
|
||||
drive->usage--;
|
||||
|
||||
idkp->openers--;
|
||||
|
||||
ide_disk_put(idkp);
|
||||
|
||||
|
@ -348,15 +348,14 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
|
||||
static int config_drive_for_dma (ide_drive_t *drive)
|
||||
{
|
||||
struct hd_driveid *id = drive->id;
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
|
||||
if ((id->capability & 1) && hwif->autodma) {
|
||||
if ((id->capability & 1) && drive->hwif->autodma) {
|
||||
/*
|
||||
* Enable DMA on any drive that has
|
||||
* UltraDMA (mode 0/1/2/3/4/5/6) enabled
|
||||
*/
|
||||
if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f))
|
||||
return hwif->ide_dma_on(drive);
|
||||
return 0;
|
||||
/*
|
||||
* Enable DMA on any drive that has mode2 DMA
|
||||
* (multi or single) enabled
|
||||
@ -364,14 +363,14 @@ static int config_drive_for_dma (ide_drive_t *drive)
|
||||
if (id->field_valid & 2) /* regular DMA */
|
||||
if ((id->dma_mword & 0x404) == 0x404 ||
|
||||
(id->dma_1word & 0x404) == 0x404)
|
||||
return hwif->ide_dma_on(drive);
|
||||
return 0;
|
||||
|
||||
/* Consult the list of known "good" drives */
|
||||
if (__ide_dma_good_drive(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
return 0;
|
||||
}
|
||||
// if (hwif->tuneproc != NULL) hwif->tuneproc(drive, 255);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -415,72 +414,68 @@ static int dma_timer_expiry (ide_drive_t *drive)
|
||||
}
|
||||
|
||||
/**
|
||||
* __ide_dma_host_off - Generic DMA kill
|
||||
* ide_dma_host_off - Generic DMA kill
|
||||
* @drive: drive to control
|
||||
*
|
||||
* Perform the generic IDE controller DMA off operation. This
|
||||
* works for most IDE bus mastering controllers
|
||||
*/
|
||||
|
||||
int __ide_dma_host_off (ide_drive_t *drive)
|
||||
void ide_dma_host_off(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
u8 unit = (drive->select.b.unit & 0x01);
|
||||
u8 dma_stat = hwif->INB(hwif->dma_status);
|
||||
|
||||
hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__ide_dma_host_off);
|
||||
EXPORT_SYMBOL(ide_dma_host_off);
|
||||
|
||||
/**
|
||||
* __ide_dma_host_off_quietly - Generic DMA kill
|
||||
* ide_dma_off_quietly - Generic DMA kill
|
||||
* @drive: drive to control
|
||||
*
|
||||
* Turn off the current DMA on this IDE controller.
|
||||
*/
|
||||
|
||||
int __ide_dma_off_quietly (ide_drive_t *drive)
|
||||
void ide_dma_off_quietly(ide_drive_t *drive)
|
||||
{
|
||||
drive->using_dma = 0;
|
||||
ide_toggle_bounce(drive, 0);
|
||||
|
||||
if (HWIF(drive)->ide_dma_host_off(drive))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
drive->hwif->dma_host_off(drive);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__ide_dma_off_quietly);
|
||||
EXPORT_SYMBOL(ide_dma_off_quietly);
|
||||
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
|
||||
|
||||
/**
|
||||
* __ide_dma_off - disable DMA on a device
|
||||
* ide_dma_off - disable DMA on a device
|
||||
* @drive: drive to disable DMA on
|
||||
*
|
||||
* Disable IDE DMA for a device on this IDE controller.
|
||||
* Inform the user that DMA has been disabled.
|
||||
*/
|
||||
|
||||
int __ide_dma_off (ide_drive_t *drive)
|
||||
void ide_dma_off(ide_drive_t *drive)
|
||||
{
|
||||
printk(KERN_INFO "%s: DMA disabled\n", drive->name);
|
||||
return HWIF(drive)->ide_dma_off_quietly(drive);
|
||||
drive->hwif->dma_off_quietly(drive);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__ide_dma_off);
|
||||
EXPORT_SYMBOL(ide_dma_off);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
|
||||
/**
|
||||
* __ide_dma_host_on - Enable DMA on a host
|
||||
* ide_dma_host_on - Enable DMA on a host
|
||||
* @drive: drive to enable for DMA
|
||||
*
|
||||
* Enable DMA on an IDE controller following generic bus mastering
|
||||
* IDE controller behaviour
|
||||
*/
|
||||
|
||||
int __ide_dma_host_on (ide_drive_t *drive)
|
||||
|
||||
void ide_dma_host_on(ide_drive_t *drive)
|
||||
{
|
||||
if (drive->using_dma) {
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
@ -488,12 +483,10 @@ int __ide_dma_host_on (ide_drive_t *drive)
|
||||
u8 dma_stat = hwif->INB(hwif->dma_status);
|
||||
|
||||
hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(__ide_dma_host_on);
|
||||
EXPORT_SYMBOL(ide_dma_host_on);
|
||||
|
||||
/**
|
||||
* __ide_dma_on - Enable DMA on a device
|
||||
@ -511,8 +504,7 @@ int __ide_dma_on (ide_drive_t *drive)
|
||||
drive->using_dma = 1;
|
||||
ide_toggle_bounce(drive, 1);
|
||||
|
||||
if (HWIF(drive)->ide_dma_host_on(drive))
|
||||
return 1;
|
||||
drive->hwif->dma_host_on(drive);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -565,7 +557,10 @@ int ide_dma_setup(ide_drive_t *drive)
|
||||
}
|
||||
|
||||
/* PRD table */
|
||||
hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable);
|
||||
if (hwif->mmio)
|
||||
writel(hwif->dmatable_dma, (void __iomem *)hwif->dma_prdtable);
|
||||
else
|
||||
outl(hwif->dmatable_dma, hwif->dma_prdtable);
|
||||
|
||||
/* specify r/w */
|
||||
hwif->OUTB(reading, hwif->dma_command);
|
||||
@ -680,6 +675,9 @@ int ide_use_dma(ide_drive_t *drive)
|
||||
struct hd_driveid *id = drive->id;
|
||||
ide_hwif_t *hwif = drive->hwif;
|
||||
|
||||
if ((id->capability & 1) == 0 || drive->autodma == 0)
|
||||
return 0;
|
||||
|
||||
/* consult the list of known "bad" drives */
|
||||
if (__ide_dma_bad_drive(drive))
|
||||
return 0;
|
||||
@ -753,12 +751,37 @@ void ide_dma_verbose(ide_drive_t *drive)
|
||||
return;
|
||||
bug_dma_off:
|
||||
printk(", BUG DMA OFF");
|
||||
hwif->ide_dma_off_quietly(drive);
|
||||
hwif->dma_off_quietly(drive);
|
||||
return;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(ide_dma_verbose);
|
||||
|
||||
int ide_set_dma(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = drive->hwif;
|
||||
int rc;
|
||||
|
||||
rc = hwif->ide_dma_check(drive);
|
||||
|
||||
switch(rc) {
|
||||
case -1: /* DMA needs to be disabled */
|
||||
hwif->dma_off_quietly(drive);
|
||||
return 0;
|
||||
case 0: /* DMA needs to be enabled */
|
||||
return hwif->ide_dma_on(drive);
|
||||
case 1: /* DMA setting cannot be changed */
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ide_set_dma);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
|
||||
int __ide_dma_lostirq (ide_drive_t *drive)
|
||||
{
|
||||
@ -809,7 +832,7 @@ int ide_release_dma(ide_hwif_t *hwif)
|
||||
{
|
||||
ide_release_dma_engine(hwif);
|
||||
|
||||
if (hwif->mmio == 2)
|
||||
if (hwif->mmio)
|
||||
return 1;
|
||||
else
|
||||
return ide_release_iomio_dma(hwif);
|
||||
@ -878,9 +901,9 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
|
||||
|
||||
static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
|
||||
{
|
||||
if (hwif->mmio == 2)
|
||||
if (hwif->mmio)
|
||||
return ide_mapped_mmio_dma(hwif, base,ports);
|
||||
BUG_ON(hwif->mmio == 1);
|
||||
|
||||
return ide_iomio_dma(hwif, base, ports);
|
||||
}
|
||||
|
||||
@ -908,14 +931,14 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
|
||||
if (!(hwif->dma_prdtable))
|
||||
hwif->dma_prdtable = (hwif->dma_base + 4);
|
||||
|
||||
if (!hwif->ide_dma_off_quietly)
|
||||
hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
|
||||
if (!hwif->ide_dma_host_off)
|
||||
hwif->ide_dma_host_off = &__ide_dma_host_off;
|
||||
if (!hwif->dma_off_quietly)
|
||||
hwif->dma_off_quietly = &ide_dma_off_quietly;
|
||||
if (!hwif->dma_host_off)
|
||||
hwif->dma_host_off = &ide_dma_host_off;
|
||||
if (!hwif->ide_dma_on)
|
||||
hwif->ide_dma_on = &__ide_dma_on;
|
||||
if (!hwif->ide_dma_host_on)
|
||||
hwif->ide_dma_host_on = &__ide_dma_host_on;
|
||||
if (!hwif->dma_host_on)
|
||||
hwif->dma_host_on = &ide_dma_host_on;
|
||||
if (!hwif->ide_dma_check)
|
||||
hwif->ide_dma_check = &__ide_dma_check;
|
||||
if (!hwif->dma_setup)
|
||||
|
@ -279,6 +279,7 @@ typedef struct ide_floppy_obj {
|
||||
ide_driver_t *driver;
|
||||
struct gendisk *disk;
|
||||
struct kref kref;
|
||||
unsigned int openers; /* protected by BKL for now */
|
||||
|
||||
/* Current packet command */
|
||||
idefloppy_pc_t *pc;
|
||||
@ -866,7 +867,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
|
||||
if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
|
||||
printk(KERN_ERR "ide-floppy: The floppy wants to issue "
|
||||
"more interrupts in DMA mode\n");
|
||||
(void)__ide_dma_off(drive);
|
||||
ide_dma_off(drive);
|
||||
return ide_do_reset(drive);
|
||||
}
|
||||
|
||||
@ -1096,9 +1097,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
|
||||
pc->current_position = pc->buffer;
|
||||
bcount.all = min(pc->request_transfer, 63 * 1024);
|
||||
|
||||
if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
|
||||
(void)__ide_dma_off(drive);
|
||||
}
|
||||
if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags))
|
||||
ide_dma_off(drive);
|
||||
|
||||
feature.all = 0;
|
||||
|
||||
if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
|
||||
@ -1433,7 +1434,8 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
|
||||
|
||||
drive->bios_cyl = 0;
|
||||
drive->bios_head = drive->bios_sect = 0;
|
||||
floppy->blocks = floppy->bs_factor = 0;
|
||||
floppy->blocks = 0;
|
||||
floppy->bs_factor = 1;
|
||||
set_capacity(floppy->disk, 0);
|
||||
|
||||
idefloppy_create_read_capacity_cmd(&pc);
|
||||
@ -1949,9 +1951,9 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
|
||||
|
||||
drive = floppy->drive;
|
||||
|
||||
drive->usage++;
|
||||
floppy->openers++;
|
||||
|
||||
if (drive->usage == 1) {
|
||||
if (floppy->openers == 1) {
|
||||
clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
|
||||
/* Just in case */
|
||||
|
||||
@ -1969,13 +1971,11 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
|
||||
** capacity of the drive or begin the format - Sam
|
||||
*/
|
||||
) {
|
||||
drive->usage--;
|
||||
ret = -EIO;
|
||||
goto out_put_floppy;
|
||||
}
|
||||
|
||||
if (floppy->wp && (filp->f_mode & 2)) {
|
||||
drive->usage--;
|
||||
ret = -EROFS;
|
||||
goto out_put_floppy;
|
||||
}
|
||||
@ -1987,13 +1987,13 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
|
||||
}
|
||||
check_disk_change(inode->i_bdev);
|
||||
} else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) {
|
||||
drive->usage--;
|
||||
ret = -EBUSY;
|
||||
goto out_put_floppy;
|
||||
}
|
||||
return 0;
|
||||
|
||||
out_put_floppy:
|
||||
floppy->openers--;
|
||||
ide_floppy_put(floppy);
|
||||
return ret;
|
||||
}
|
||||
@ -2007,7 +2007,7 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
|
||||
|
||||
debug_log(KERN_INFO "Reached idefloppy_release\n");
|
||||
|
||||
if (drive->usage == 1) {
|
||||
if (floppy->openers == 1) {
|
||||
/* IOMEGA Clik! drives do not support lock/unlock commands */
|
||||
if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
|
||||
idefloppy_create_prevent_cmd(&pc, 0);
|
||||
@ -2016,7 +2016,8 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
|
||||
|
||||
clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
|
||||
}
|
||||
drive->usage--;
|
||||
|
||||
floppy->openers--;
|
||||
|
||||
ide_floppy_put(floppy);
|
||||
|
||||
@ -2050,7 +2051,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
|
||||
prevent = 0;
|
||||
/* fall through */
|
||||
case CDROM_LOCKDOOR:
|
||||
if (drive->usage > 1)
|
||||
if (floppy->openers > 1)
|
||||
return -EBUSY;
|
||||
|
||||
/* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
|
||||
@ -2072,7 +2073,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
|
||||
if (!(file->f_mode & 2))
|
||||
return -EPERM;
|
||||
|
||||
if (drive->usage > 1) {
|
||||
if (floppy->openers > 1) {
|
||||
/* Don't format if someone is using the disk */
|
||||
|
||||
clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,
|
||||
|
@ -226,7 +226,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
|
||||
break;
|
||||
if (drive->hwif->ide_dma_check == NULL)
|
||||
break;
|
||||
drive->hwif->ide_dma_check(drive);
|
||||
ide_set_dma(drive);
|
||||
break;
|
||||
}
|
||||
pm->pm_step = ide_pm_state_completed;
|
||||
@ -1351,7 +1351,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
|
||||
*/
|
||||
drive->retry_pio++;
|
||||
drive->state = DMA_PIO_RETRY;
|
||||
(void) hwif->ide_dma_off_quietly(drive);
|
||||
hwif->dma_off_quietly(drive);
|
||||
|
||||
/*
|
||||
* un-busy drive etc (hwgroup->busy is cleared on return) and
|
||||
@ -1646,6 +1646,17 @@ irqreturn_t ide_intr (int irq, void *dev_id)
|
||||
del_timer(&hwgroup->timer);
|
||||
spin_unlock(&ide_lock);
|
||||
|
||||
/* Some controllers might set DMA INTR no matter DMA or PIO;
|
||||
* bmdma status might need to be cleared even for
|
||||
* PIO interrupts to prevent spurious/lost irq.
|
||||
*/
|
||||
if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma))
|
||||
/* ide_dma_end() needs bmdma status for error checking.
|
||||
* So, skip clearing bmdma status here and leave it
|
||||
* to ide_dma_end() if this is dma interrupt.
|
||||
*/
|
||||
hwif->ide_dma_clear_irq(drive);
|
||||
|
||||
if (drive->unmask)
|
||||
local_irq_enable_in_hardirq();
|
||||
/* service this interrupt, may set handler for next interrupt */
|
||||
|
@ -49,11 +49,6 @@ static void ide_insw (unsigned long port, void *addr, u32 count)
|
||||
insw(port, addr, count);
|
||||
}
|
||||
|
||||
static u32 ide_inl (unsigned long port)
|
||||
{
|
||||
return (u32) inl(port);
|
||||
}
|
||||
|
||||
static void ide_insl (unsigned long port, void *addr, u32 count)
|
||||
{
|
||||
insl(port, addr, count);
|
||||
@ -79,11 +74,6 @@ static void ide_outsw (unsigned long port, void *addr, u32 count)
|
||||
outsw(port, addr, count);
|
||||
}
|
||||
|
||||
static void ide_outl (u32 val, unsigned long port)
|
||||
{
|
||||
outl(val, port);
|
||||
}
|
||||
|
||||
static void ide_outsl (unsigned long port, void *addr, u32 count)
|
||||
{
|
||||
outsl(port, addr, count);
|
||||
@ -94,12 +84,10 @@ void default_hwif_iops (ide_hwif_t *hwif)
|
||||
hwif->OUTB = ide_outb;
|
||||
hwif->OUTBSYNC = ide_outbsync;
|
||||
hwif->OUTW = ide_outw;
|
||||
hwif->OUTL = ide_outl;
|
||||
hwif->OUTSW = ide_outsw;
|
||||
hwif->OUTSL = ide_outsl;
|
||||
hwif->INB = ide_inb;
|
||||
hwif->INW = ide_inw;
|
||||
hwif->INL = ide_inl;
|
||||
hwif->INSW = ide_insw;
|
||||
hwif->INSL = ide_insl;
|
||||
}
|
||||
@ -123,11 +111,6 @@ static void ide_mm_insw (unsigned long port, void *addr, u32 count)
|
||||
__ide_mm_insw((void __iomem *) port, addr, count);
|
||||
}
|
||||
|
||||
static u32 ide_mm_inl (unsigned long port)
|
||||
{
|
||||
return (u32) readl((void __iomem *) port);
|
||||
}
|
||||
|
||||
static void ide_mm_insl (unsigned long port, void *addr, u32 count)
|
||||
{
|
||||
__ide_mm_insl((void __iomem *) port, addr, count);
|
||||
@ -153,11 +136,6 @@ static void ide_mm_outsw (unsigned long port, void *addr, u32 count)
|
||||
__ide_mm_outsw((void __iomem *) port, addr, count);
|
||||
}
|
||||
|
||||
static void ide_mm_outl (u32 value, unsigned long port)
|
||||
{
|
||||
writel(value, (void __iomem *) port);
|
||||
}
|
||||
|
||||
static void ide_mm_outsl (unsigned long port, void *addr, u32 count)
|
||||
{
|
||||
__ide_mm_outsl((void __iomem *) port, addr, count);
|
||||
@ -170,12 +148,10 @@ void default_hwif_mmiops (ide_hwif_t *hwif)
|
||||
this one is controller specific! */
|
||||
hwif->OUTBSYNC = ide_mm_outbsync;
|
||||
hwif->OUTW = ide_mm_outw;
|
||||
hwif->OUTL = ide_mm_outl;
|
||||
hwif->OUTSW = ide_mm_outsw;
|
||||
hwif->OUTSL = ide_mm_outsl;
|
||||
hwif->INB = ide_mm_inb;
|
||||
hwif->INW = ide_mm_inw;
|
||||
hwif->INL = ide_mm_inl;
|
||||
hwif->INSW = ide_mm_insw;
|
||||
hwif->INSL = ide_mm_insl;
|
||||
}
|
||||
@ -777,7 +753,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDEDMA
|
||||
if (hwif->ide_dma_check) /* check if host supports DMA */
|
||||
hwif->ide_dma_host_off(drive);
|
||||
hwif->dma_host_off(drive);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -854,9 +830,9 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDEDMA
|
||||
if (speed >= XFER_SW_DMA_0)
|
||||
hwif->ide_dma_host_on(drive);
|
||||
hwif->dma_host_on(drive);
|
||||
else if (hwif->ide_dma_check) /* check if host supports DMA */
|
||||
hwif->ide_dma_off_quietly(drive);
|
||||
hwif->dma_off_quietly(drive);
|
||||
#endif
|
||||
|
||||
switch(speed) {
|
||||
@ -1066,12 +1042,12 @@ static void check_dma_crc(ide_drive_t *drive)
|
||||
{
|
||||
#ifdef CONFIG_BLK_DEV_IDEDMA
|
||||
if (drive->crc_count) {
|
||||
(void) HWIF(drive)->ide_dma_off_quietly(drive);
|
||||
drive->hwif->dma_off_quietly(drive);
|
||||
ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
|
||||
if (drive->current_speed >= XFER_SW_DMA_0)
|
||||
(void) HWIF(drive)->ide_dma_on(drive);
|
||||
} else
|
||||
(void)__ide_dma_off(drive);
|
||||
ide_dma_off(drive);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -205,6 +205,21 @@ int ide_dma_enable (ide_drive_t *drive)
|
||||
|
||||
EXPORT_SYMBOL(ide_dma_enable);
|
||||
|
||||
int ide_use_fast_pio(ide_drive_t *drive)
|
||||
{
|
||||
struct hd_driveid *id = drive->id;
|
||||
|
||||
if ((id->capability & 1) && drive->autodma)
|
||||
return 1;
|
||||
|
||||
if ((id->capability & 8) || (id->field_valid & 2))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ide_use_fast_pio);
|
||||
|
||||
/*
|
||||
* Standard (generic) timings for PIO modes, from ATA2 specification.
|
||||
* These timings are for access to the IDE data port register *only*.
|
||||
@ -349,7 +364,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p
|
||||
int use_iordy = 0;
|
||||
struct hd_driveid* id = drive->id;
|
||||
int overridden = 0;
|
||||
int blacklisted = 0;
|
||||
|
||||
if (mode_wanted != 255) {
|
||||
pio_mode = mode_wanted;
|
||||
@ -357,7 +371,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p
|
||||
pio_mode = 0;
|
||||
} else if ((pio_mode = ide_scan_pio_blacklist(id->model)) != -1) {
|
||||
overridden = 1;
|
||||
blacklisted = 1;
|
||||
use_iordy = (pio_mode > 2);
|
||||
} else {
|
||||
pio_mode = id->tPIO;
|
||||
@ -409,7 +422,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p
|
||||
d->cycle_time = cycle_time ? cycle_time : ide_pio_timings[pio_mode].cycle_time;
|
||||
d->use_iordy = use_iordy;
|
||||
d->overridden = overridden;
|
||||
d->blacklisted = blacklisted;
|
||||
}
|
||||
return pio_mode;
|
||||
}
|
||||
@ -462,8 +474,6 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
|
||||
return -1;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(ide_set_xfer_rate);
|
||||
|
||||
static void ide_dump_opcode(ide_drive_t *drive)
|
||||
{
|
||||
struct request *rq;
|
||||
|
@ -853,11 +853,11 @@ static void probe_hwif(ide_hwif_t *hwif)
|
||||
* things, if not checked and cleared.
|
||||
* PARANOIA!!!
|
||||
*/
|
||||
hwif->ide_dma_off_quietly(drive);
|
||||
hwif->dma_off_quietly(drive);
|
||||
#ifdef CONFIG_IDEDMA_ONLYDISK
|
||||
if (drive->media == ide_disk)
|
||||
#endif
|
||||
hwif->ide_dma_check(drive);
|
||||
ide_set_dma(drive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1970,7 +1970,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
|
||||
printk(KERN_ERR "ide-tape: The tape wants to issue more "
|
||||
"interrupts in DMA mode\n");
|
||||
printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
|
||||
(void)__ide_dma_off(drive);
|
||||
ide_dma_off(drive);
|
||||
return ide_do_reset(drive);
|
||||
}
|
||||
/* Get the number of bytes to transfer on this interrupt. */
|
||||
@ -2176,7 +2176,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
|
||||
if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
|
||||
printk(KERN_WARNING "ide-tape: DMA disabled, "
|
||||
"reverting to PIO\n");
|
||||
(void)__ide_dma_off(drive);
|
||||
ide_dma_off(drive);
|
||||
}
|
||||
if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
|
||||
dma_ok = !hwif->dma_setup(drive);
|
||||
@ -4792,15 +4792,10 @@ static int idetape_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct gendisk *disk = inode->i_bdev->bd_disk;
|
||||
struct ide_tape_obj *tape;
|
||||
ide_drive_t *drive;
|
||||
|
||||
if (!(tape = ide_tape_get(disk)))
|
||||
return -ENXIO;
|
||||
|
||||
drive = tape->drive;
|
||||
|
||||
drive->usage++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4808,9 +4803,6 @@ static int idetape_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct gendisk *disk = inode->i_bdev->bd_disk;
|
||||
struct ide_tape_obj *tape = ide_tape_g(disk);
|
||||
ide_drive_t *drive = tape->drive;
|
||||
|
||||
drive->usage--;
|
||||
|
||||
ide_tape_put(tape);
|
||||
|
||||
|
@ -389,9 +389,8 @@ int ide_hwif_request_regions(ide_hwif_t *hwif)
|
||||
unsigned long addr;
|
||||
unsigned int i;
|
||||
|
||||
if (hwif->mmio == 2)
|
||||
if (hwif->mmio)
|
||||
return 0;
|
||||
BUG_ON(hwif->mmio == 1);
|
||||
addr = hwif->io_ports[IDE_CONTROL_OFFSET];
|
||||
if (addr && !hwif_request_region(hwif, addr, 1))
|
||||
goto control_region_busy;
|
||||
@ -438,7 +437,7 @@ void ide_hwif_release_regions(ide_hwif_t *hwif)
|
||||
{
|
||||
u32 i = 0;
|
||||
|
||||
if (hwif->mmio == 2)
|
||||
if (hwif->mmio)
|
||||
return;
|
||||
if (hwif->io_ports[IDE_CONTROL_OFFSET])
|
||||
release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
|
||||
@ -507,23 +506,22 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
|
||||
hwif->ide_dma_end = tmp_hwif->ide_dma_end;
|
||||
hwif->ide_dma_check = tmp_hwif->ide_dma_check;
|
||||
hwif->ide_dma_on = tmp_hwif->ide_dma_on;
|
||||
hwif->ide_dma_off_quietly = tmp_hwif->ide_dma_off_quietly;
|
||||
hwif->dma_off_quietly = tmp_hwif->dma_off_quietly;
|
||||
hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq;
|
||||
hwif->ide_dma_host_on = tmp_hwif->ide_dma_host_on;
|
||||
hwif->ide_dma_host_off = tmp_hwif->ide_dma_host_off;
|
||||
hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq;
|
||||
hwif->dma_host_on = tmp_hwif->dma_host_on;
|
||||
hwif->dma_host_off = tmp_hwif->dma_host_off;
|
||||
hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq;
|
||||
hwif->ide_dma_timeout = tmp_hwif->ide_dma_timeout;
|
||||
|
||||
hwif->OUTB = tmp_hwif->OUTB;
|
||||
hwif->OUTBSYNC = tmp_hwif->OUTBSYNC;
|
||||
hwif->OUTW = tmp_hwif->OUTW;
|
||||
hwif->OUTL = tmp_hwif->OUTL;
|
||||
hwif->OUTSW = tmp_hwif->OUTSW;
|
||||
hwif->OUTSL = tmp_hwif->OUTSL;
|
||||
|
||||
hwif->INB = tmp_hwif->INB;
|
||||
hwif->INW = tmp_hwif->INW;
|
||||
hwif->INL = tmp_hwif->INL;
|
||||
hwif->INSW = tmp_hwif->INSW;
|
||||
hwif->INSL = tmp_hwif->INSL;
|
||||
|
||||
@ -551,7 +549,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
|
||||
hwif->extra_ports = tmp_hwif->extra_ports;
|
||||
hwif->autodma = tmp_hwif->autodma;
|
||||
hwif->udma_four = tmp_hwif->udma_four;
|
||||
hwif->no_dsc = tmp_hwif->no_dsc;
|
||||
|
||||
hwif->hwif_data = tmp_hwif->hwif_data;
|
||||
}
|
||||
@ -1138,12 +1135,11 @@ static int set_using_dma (ide_drive_t *drive, int arg)
|
||||
if (HWIF(drive)->ide_dma_check == NULL)
|
||||
return -EPERM;
|
||||
if (arg) {
|
||||
if (HWIF(drive)->ide_dma_check(drive)) return -EIO;
|
||||
if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
|
||||
} else {
|
||||
if (__ide_dma_off(drive))
|
||||
if (ide_set_dma(drive))
|
||||
return -EIO;
|
||||
}
|
||||
if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
|
||||
} else
|
||||
ide_dma_off(drive);
|
||||
return 0;
|
||||
#else
|
||||
return -EPERM;
|
||||
|
@ -215,7 +215,7 @@ void __init buddha_init(void)
|
||||
|
||||
index = ide_register_hw(&hw, &hwif);
|
||||
if (index != -1) {
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
printk("ide%d: ", index);
|
||||
switch(type) {
|
||||
case BOARD_BUDDHA:
|
||||
|
@ -167,7 +167,7 @@ void __init gayle_init(void)
|
||||
|
||||
index = ide_register_hw(&hw, &hwif);
|
||||
if (index != -1) {
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
switch (i) {
|
||||
case 0:
|
||||
printk("ide%d: Gayle IDE interface (A%d style)\n", index,
|
||||
|
@ -143,16 +143,16 @@ static void ht6560b_selectproc (ide_drive_t *drive)
|
||||
current_timing = timing;
|
||||
if (drive->media != ide_disk || !drive->present)
|
||||
select |= HT_PREFETCH_MODE;
|
||||
(void) HWIF(drive)->INB(HT_CONFIG_PORT);
|
||||
(void) HWIF(drive)->INB(HT_CONFIG_PORT);
|
||||
(void) HWIF(drive)->INB(HT_CONFIG_PORT);
|
||||
(void) HWIF(drive)->INB(HT_CONFIG_PORT);
|
||||
HWIF(drive)->OUTB(select, HT_CONFIG_PORT);
|
||||
(void)inb(HT_CONFIG_PORT);
|
||||
(void)inb(HT_CONFIG_PORT);
|
||||
(void)inb(HT_CONFIG_PORT);
|
||||
(void)inb(HT_CONFIG_PORT);
|
||||
outb(select, HT_CONFIG_PORT);
|
||||
/*
|
||||
* Set timing for this drive:
|
||||
*/
|
||||
HWIF(drive)->OUTB(timing, IDE_SELECT_REG);
|
||||
(void) HWIF(drive)->INB(IDE_STATUS_REG);
|
||||
outb(timing, IDE_SELECT_REG);
|
||||
(void)inb(IDE_STATUS_REG);
|
||||
#ifdef DEBUG
|
||||
printk("ht6560b: %s: select=%#x timing=%#x\n",
|
||||
drive->name, select, timing);
|
||||
|
@ -141,7 +141,7 @@ void macide_init(void)
|
||||
}
|
||||
|
||||
if (index != -1) {
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
if (macintosh_config->ide_type == MAC_IDE_QUADRA)
|
||||
printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index);
|
||||
else if (macintosh_config->ide_type == MAC_IDE_PB)
|
||||
|
@ -145,7 +145,7 @@ void q40ide_init(void)
|
||||
index = ide_register_hw(&hw, &hwif);
|
||||
// **FIXME**
|
||||
if (index != -1)
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,12 +181,6 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
|
||||
{
|
||||
int mem_sttime;
|
||||
int mem_stcfg;
|
||||
unsigned long mode;
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
|
||||
if (ide_use_dma(drive))
|
||||
mode = ide_dma_speed(drive, 0);
|
||||
#endif
|
||||
|
||||
mem_sttime = 0;
|
||||
mem_stcfg = au_readl(MEM_STCFG2);
|
||||
@ -195,7 +189,7 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
|
||||
auide_tune_drive(drive, speed - XFER_PIO_0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
switch(speed) {
|
||||
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
|
||||
case XFER_MW_DMA_2:
|
||||
@ -207,7 +201,6 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
|
||||
mem_stcfg &= ~TOECS_MASK;
|
||||
mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
|
||||
|
||||
mode = XFER_MW_DMA_2;
|
||||
break;
|
||||
case XFER_MW_DMA_1:
|
||||
mem_sttime = SBC_IDE_TIMING(MDMA1);
|
||||
@ -218,7 +211,6 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
|
||||
mem_stcfg &= ~TOECS_MASK;
|
||||
mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
|
||||
|
||||
mode = XFER_MW_DMA_1;
|
||||
break;
|
||||
case XFER_MW_DMA_0:
|
||||
mem_sttime = SBC_IDE_TIMING(MDMA0);
|
||||
@ -229,14 +221,13 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
|
||||
mem_stcfg &= ~TOECS_MASK;
|
||||
mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
|
||||
|
||||
mode = XFER_MW_DMA_0;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ide_config_drive_speed(drive, mode))
|
||||
|
||||
if (ide_config_drive_speed(drive, speed))
|
||||
return 1;
|
||||
|
||||
au_writel(mem_sttime,MEM_STTIME2);
|
||||
@ -423,9 +414,9 @@ static int auide_dma_check(ide_drive_t *drive)
|
||||
speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
|
||||
|
||||
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
|
||||
return HWIF(drive)->ide_dma_on(drive);
|
||||
return 0;
|
||||
|
||||
return HWIF(drive)->ide_dma_off_quietly(drive);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int auide_dma_test_irq(ide_drive_t *drive)
|
||||
@ -447,27 +438,24 @@ static int auide_dma_test_irq(ide_drive_t *drive)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int auide_dma_host_on(ide_drive_t *drive)
|
||||
static void auide_dma_host_on(ide_drive_t *drive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int auide_dma_on(ide_drive_t *drive)
|
||||
{
|
||||
drive->using_dma = 1;
|
||||
return auide_dma_host_on(drive);
|
||||
}
|
||||
|
||||
|
||||
static int auide_dma_host_off(ide_drive_t *drive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int auide_dma_off_quietly(ide_drive_t *drive)
|
||||
static void auide_dma_host_off(ide_drive_t *drive)
|
||||
{
|
||||
}
|
||||
|
||||
static void auide_dma_off_quietly(ide_drive_t *drive)
|
||||
{
|
||||
drive->using_dma = 0;
|
||||
return auide_dma_host_off(drive);
|
||||
}
|
||||
|
||||
static int auide_dma_lostirq(ide_drive_t *drive)
|
||||
@ -717,7 +705,8 @@ static int au_ide_probe(struct device *dev)
|
||||
|
||||
/* hold should be on in all cases */
|
||||
hwif->hold = 1;
|
||||
hwif->mmio = 2;
|
||||
|
||||
hwif->mmio = 1;
|
||||
|
||||
/* If the user has selected DDMA assisted copies,
|
||||
then set up a few local I/O function entry points
|
||||
@ -732,7 +721,7 @@ static int au_ide_probe(struct device *dev)
|
||||
hwif->speedproc = &auide_tune_chipset;
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
|
||||
hwif->ide_dma_off_quietly = &auide_dma_off_quietly;
|
||||
hwif->dma_off_quietly = &auide_dma_off_quietly;
|
||||
hwif->ide_dma_timeout = &auide_dma_timeout;
|
||||
|
||||
hwif->ide_dma_check = &auide_dma_check;
|
||||
@ -741,8 +730,8 @@ static int au_ide_probe(struct device *dev)
|
||||
hwif->ide_dma_end = &auide_dma_end;
|
||||
hwif->dma_setup = &auide_dma_setup;
|
||||
hwif->ide_dma_test_irq = &auide_dma_test_irq;
|
||||
hwif->ide_dma_host_off = &auide_dma_host_off;
|
||||
hwif->ide_dma_host_on = &auide_dma_host_on;
|
||||
hwif->dma_host_off = &auide_dma_host_off;
|
||||
hwif->dma_host_on = &auide_dma_host_on;
|
||||
hwif->ide_dma_lostirq = &auide_dma_lostirq;
|
||||
hwif->ide_dma_on = &auide_dma_on;
|
||||
|
||||
|
@ -115,7 +115,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
|
||||
/* Setup MMIO ops. */
|
||||
default_hwif_mmiops(hwif);
|
||||
/* Prevent resource map manipulation. */
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
hwif->noprobe = 0;
|
||||
|
||||
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
|
||||
|
@ -94,9 +94,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive)
|
||||
switch(hwif->pci_dev->device) {
|
||||
case PCI_DEVICE_ID_ARTOP_ATP865:
|
||||
case PCI_DEVICE_ID_ARTOP_ATP865R:
|
||||
mode = (hwif->INB(((hwif->channel) ?
|
||||
hwif->mate->dma_status :
|
||||
hwif->dma_status)) & 0x10) ? 4 : 3;
|
||||
mode = (inb(hwif->channel ?
|
||||
hwif->mate->dma_status :
|
||||
hwif->dma_status) & 0x10) ? 4 : 3;
|
||||
break;
|
||||
case PCI_DEVICE_ID_ARTOP_ATP860:
|
||||
case PCI_DEVICE_ID_ARTOP_ATP860R:
|
||||
@ -209,25 +209,13 @@ static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
|
||||
|
||||
static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct hd_driveid *id = drive->id;
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if ((id->capability & 1) && drive->autodma) {
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (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:
|
||||
if (ide_use_fast_pio(drive))
|
||||
aec62xx_tune_drive(drive, 5);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int aec62xx_irq_timeout (ide_drive_t *drive)
|
||||
@ -286,10 +274,8 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
|
||||
hwif->tuneproc = &aec62xx_tune_drive;
|
||||
hwif->speedproc = &aec62xx_tune_chipset;
|
||||
|
||||
if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
|
||||
if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
|
||||
hwif->serialized = hwif->channel;
|
||||
hwif->no_dsc = 1;
|
||||
}
|
||||
|
||||
if (hwif->mate)
|
||||
hwif->mate->serialized = hwif->serialized;
|
||||
|
@ -507,17 +507,15 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
*
|
||||
* Configure a drive for DMA operation. If DMA is not possible we
|
||||
* drop the drive into PIO mode instead.
|
||||
*
|
||||
* FIXME: exactly what are we trying to return here
|
||||
*/
|
||||
|
||||
|
||||
static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct hd_driveid *id = drive->id;
|
||||
|
||||
if ((m5229_revision<=0x20) && (drive->media!=ide_disk))
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
goto no_dma_set;
|
||||
|
||||
drive->init_speed = 0;
|
||||
|
||||
@ -552,9 +550,10 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
|
||||
ata_pio:
|
||||
hwif->tuneproc(drive, 255);
|
||||
no_dma_set:
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
return -1;
|
||||
}
|
||||
return hwif->ide_dma_on(drive);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -852,8 +851,8 @@ static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
|
||||
{
|
||||
if (m5229_revision < 0x20)
|
||||
return;
|
||||
if (!(hwif->channel))
|
||||
hwif->OUTB(hwif->INB(dmabase+2) & 0x60, dmabase+2);
|
||||
if (!hwif->channel)
|
||||
outb(inb(dmabase + 2) & 0x60, dmabase + 2);
|
||||
ide_setup_dma(hwif, dmabase, 8);
|
||||
}
|
||||
|
||||
|
@ -304,8 +304,9 @@ static int amd74xx_ide_dma_check(ide_drive_t *drive)
|
||||
amd_set_drive(drive, speed);
|
||||
|
||||
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
|
||||
return HWIF(drive)->ide_dma_on(drive);
|
||||
return HWIF(drive)->ide_dma_off_quietly(drive);
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -101,7 +101,7 @@ static u8 atiixp_dma_2_pio(u8 xfer_rate) {
|
||||
}
|
||||
}
|
||||
|
||||
static int atiixp_ide_dma_host_on(ide_drive_t *drive)
|
||||
static void atiixp_dma_host_on(ide_drive_t *drive)
|
||||
{
|
||||
struct pci_dev *dev = drive->hwif->pci_dev;
|
||||
unsigned long flags;
|
||||
@ -118,10 +118,10 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive)
|
||||
|
||||
spin_unlock_irqrestore(&atiixp_lock, flags);
|
||||
|
||||
return __ide_dma_host_on(drive);
|
||||
ide_dma_host_on(drive);
|
||||
}
|
||||
|
||||
static int atiixp_ide_dma_host_off(ide_drive_t *drive)
|
||||
static void atiixp_dma_host_off(ide_drive_t *drive)
|
||||
{
|
||||
struct pci_dev *dev = drive->hwif->pci_dev;
|
||||
unsigned long flags;
|
||||
@ -135,7 +135,7 @@ static int atiixp_ide_dma_host_off(ide_drive_t *drive)
|
||||
|
||||
spin_unlock_irqrestore(&atiixp_lock, flags);
|
||||
|
||||
return __ide_dma_host_off(drive);
|
||||
ide_dma_host_off(drive);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,11 +235,8 @@ static int atiixp_config_drive_for_dma(ide_drive_t *drive)
|
||||
{
|
||||
u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive));
|
||||
|
||||
/* If no DMA speed was available then disable DMA and use PIO. */
|
||||
if (!speed) {
|
||||
u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
|
||||
speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
|
||||
}
|
||||
if (!speed)
|
||||
return 0;
|
||||
|
||||
(void) atiixp_speedproc(drive, speed);
|
||||
return ide_dma_enable(drive);
|
||||
@ -255,30 +252,20 @@ static int atiixp_config_drive_for_dma(ide_drive_t *drive)
|
||||
|
||||
static int atiixp_dma_check(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct hd_driveid *id = drive->id;
|
||||
u8 tspeed, speed;
|
||||
|
||||
drive->init_speed = 0;
|
||||
|
||||
if ((id->capability & 1) && drive->autodma) {
|
||||
if (ide_use_dma(drive) && atiixp_config_drive_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (atiixp_config_drive_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:
|
||||
if (ide_use_fast_pio(drive)) {
|
||||
tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
|
||||
speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
|
||||
hwif->speedproc(drive, speed);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
atiixp_speedproc(drive, speed);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -318,8 +305,8 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
|
||||
else
|
||||
hwif->udma_four = 0;
|
||||
|
||||
hwif->ide_dma_host_on = &atiixp_ide_dma_host_on;
|
||||
hwif->ide_dma_host_off = &atiixp_ide_dma_host_off;
|
||||
hwif->dma_host_on = &atiixp_dma_host_on;
|
||||
hwif->dma_host_off = &atiixp_dma_host_off;
|
||||
hwif->ide_dma_check = &atiixp_dma_check;
|
||||
if (!noautodma)
|
||||
hwif->autodma = 1;
|
||||
|
@ -466,36 +466,21 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
if (!speed)
|
||||
return 0;
|
||||
|
||||
if(ide_set_xfer_rate(drive, speed))
|
||||
return 0;
|
||||
|
||||
if (!drive->init_speed)
|
||||
drive->init_speed = speed;
|
||||
if (cmd64x_tune_chipset(drive, speed))
|
||||
return 0;
|
||||
|
||||
return ide_dma_enable(drive);
|
||||
}
|
||||
|
||||
static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct hd_driveid *id = drive->id;
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) {
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (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:
|
||||
if (ide_use_fast_pio(drive))
|
||||
config_chipset_for_pio(drive, 1);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cmd64x_alt_dma_status (struct pci_dev *dev)
|
||||
@ -518,13 +503,13 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive)
|
||||
|
||||
drive->waiting_for_dma = 0;
|
||||
/* read DMA command state */
|
||||
dma_cmd = hwif->INB(hwif->dma_command);
|
||||
dma_cmd = inb(hwif->dma_command);
|
||||
/* stop DMA */
|
||||
hwif->OUTB((dma_cmd & ~1), hwif->dma_command);
|
||||
outb(dma_cmd & ~1, hwif->dma_command);
|
||||
/* get DMA status */
|
||||
dma_stat = hwif->INB(hwif->dma_status);
|
||||
dma_stat = inb(hwif->dma_status);
|
||||
/* clear the INTR & ERROR bits */
|
||||
hwif->OUTB(dma_stat|6, hwif->dma_status);
|
||||
outb(dma_stat | 6, hwif->dma_status);
|
||||
if (cmd64x_alt_dma_status(dev)) {
|
||||
u8 dma_intr = 0;
|
||||
u8 dma_mask = (hwif->channel) ? ARTTIM23_INTR_CH1 :
|
||||
@ -546,7 +531,7 @@ static int cmd64x_ide_dma_test_irq (ide_drive_t *drive)
|
||||
struct pci_dev *dev = hwif->pci_dev;
|
||||
u8 dma_alt_stat = 0, mask = (hwif->channel) ? MRDMODE_INTR_CH1 :
|
||||
MRDMODE_INTR_CH0;
|
||||
u8 dma_stat = hwif->INB(hwif->dma_status);
|
||||
u8 dma_stat = inb(hwif->dma_status);
|
||||
|
||||
(void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
|
||||
#ifdef DEBUG
|
||||
@ -576,13 +561,13 @@ static int cmd646_1_ide_dma_end (ide_drive_t *drive)
|
||||
|
||||
drive->waiting_for_dma = 0;
|
||||
/* get DMA status */
|
||||
dma_stat = hwif->INB(hwif->dma_status);
|
||||
dma_stat = inb(hwif->dma_status);
|
||||
/* read DMA command state */
|
||||
dma_cmd = hwif->INB(hwif->dma_command);
|
||||
dma_cmd = inb(hwif->dma_command);
|
||||
/* stop DMA */
|
||||
hwif->OUTB((dma_cmd & ~1), hwif->dma_command);
|
||||
outb(dma_cmd & ~1, hwif->dma_command);
|
||||
/* clear the INTR & ERROR bits */
|
||||
hwif->OUTB(dma_stat|6, hwif->dma_status);
|
||||
outb(dma_stat | 6, hwif->dma_status);
|
||||
/* and free any DMA resources */
|
||||
ide_destroy_dmatable(drive);
|
||||
/* verify good DMA status */
|
||||
|
@ -132,12 +132,11 @@ static void cs5520_tune_drive(ide_drive_t *drive, u8 pio)
|
||||
|
||||
static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
|
||||
/* Tune the drive for PIO modes up to PIO 4 */
|
||||
cs5520_tune_drive(drive, 4);
|
||||
|
||||
/* Then tell the core to use DMA operations */
|
||||
return hwif->ide_dma_on(drive);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -81,8 +81,8 @@ static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autot
|
||||
|
||||
pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
|
||||
if (!cs5530_set_xfer_mode(drive, modes[pio])) {
|
||||
format = (hwif->INL(basereg+4) >> 31) & 1;
|
||||
hwif->OUTL(cs5530_pio_timings[format][pio],
|
||||
format = (inl(basereg + 4) >> 31) & 1;
|
||||
outl(cs5530_pio_timings[format][pio],
|
||||
basereg+(drive->select.b.unit<<3));
|
||||
}
|
||||
}
|
||||
@ -103,16 +103,13 @@ static int cs5530_config_dma (ide_drive_t *drive)
|
||||
int unit = drive->select.b.unit;
|
||||
ide_drive_t *mate = &hwif->drives[unit^1];
|
||||
struct hd_driveid *id = drive->id;
|
||||
unsigned int reg, timings;
|
||||
unsigned int reg, timings = 0;
|
||||
unsigned long basereg;
|
||||
|
||||
/*
|
||||
* Default to DMA-off in case we run into trouble here.
|
||||
*/
|
||||
hwif->ide_dma_off_quietly(drive);
|
||||
/* turn off DMA while we fiddle */
|
||||
hwif->ide_dma_host_off(drive);
|
||||
/* clear DMA_capable bit */
|
||||
hwif->dma_off_quietly(drive);
|
||||
|
||||
/*
|
||||
* The CS5530 specifies that two drives sharing a cable cannot
|
||||
@ -182,30 +179,24 @@ static int cs5530_config_dma (ide_drive_t *drive)
|
||||
case XFER_MW_DMA_1: timings = 0x00012121; break;
|
||||
case XFER_MW_DMA_2: timings = 0x00002020; break;
|
||||
default:
|
||||
printk(KERN_ERR "%s: cs5530_config_dma: huh? mode=%02x\n",
|
||||
drive->name, mode);
|
||||
return 1; /* failure */
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
basereg = CS5530_BASEREG(hwif);
|
||||
reg = hwif->INL(basereg+4); /* get drive0 config register */
|
||||
reg = inl(basereg + 4); /* get drive0 config register */
|
||||
timings |= reg & 0x80000000; /* preserve PIO format bit */
|
||||
if (unit == 0) { /* are we configuring drive0? */
|
||||
hwif->OUTL(timings, basereg+4); /* write drive0 config register */
|
||||
outl(timings, basereg + 4); /* write drive0 config register */
|
||||
} else {
|
||||
if (timings & 0x00100000)
|
||||
reg |= 0x00100000; /* enable UDMA timings for both drives */
|
||||
else
|
||||
reg &= ~0x00100000; /* disable UDMA timings for both drives */
|
||||
hwif->OUTL(reg, basereg+4); /* write drive0 config register */
|
||||
hwif->OUTL(timings, basereg+12); /* write drive1 config register */
|
||||
outl(reg, basereg + 4); /* write drive0 config register */
|
||||
outl(timings, basereg + 12); /* write drive1 config register */
|
||||
}
|
||||
(void) hwif->ide_dma_host_on(drive);
|
||||
/* set DMA_capable bit */
|
||||
|
||||
/*
|
||||
* Finally, turn DMA on in software, and exit.
|
||||
*/
|
||||
return hwif->ide_dma_on(drive); /* success */
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
/**
|
||||
@ -321,17 +312,17 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
|
||||
|
||||
hwif->tuneproc = &cs5530_tuneproc;
|
||||
basereg = CS5530_BASEREG(hwif);
|
||||
d0_timings = hwif->INL(basereg+0);
|
||||
d0_timings = inl(basereg + 0);
|
||||
if (CS5530_BAD_PIO(d0_timings)) {
|
||||
/* PIO timings not initialized? */
|
||||
hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+0);
|
||||
outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 0);
|
||||
if (!hwif->drives[0].autotune)
|
||||
hwif->drives[0].autotune = 1;
|
||||
/* needs autotuning later */
|
||||
}
|
||||
if (CS5530_BAD_PIO(hwif->INL(basereg+8))) {
|
||||
/* PIO timings not initialized? */
|
||||
hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+8);
|
||||
if (CS5530_BAD_PIO(inl(basereg + 8))) {
|
||||
/* PIO timings not initialized? */
|
||||
outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 8);
|
||||
if (!hwif->drives[1].autotune)
|
||||
hwif->drives[1].autotune = 1;
|
||||
/* needs autotuning later */
|
||||
|
@ -195,28 +195,19 @@ static int cs5535_config_drive_for_dma(ide_drive_t *drive)
|
||||
|
||||
static int cs5535_dma_check(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = drive->hwif;
|
||||
struct hd_driveid *id = drive->id;
|
||||
u8 speed;
|
||||
|
||||
drive->init_speed = 0;
|
||||
|
||||
if ((id->capability & 1) && drive->autodma) {
|
||||
if (ide_use_dma(drive)) {
|
||||
if (cs5535_config_drive_for_dma(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
}
|
||||
if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
goto fast_ata_pio;
|
||||
|
||||
} else if ((id->capability & 8) || (id->field_valid & 2)) {
|
||||
fast_ata_pio:
|
||||
if (ide_use_fast_pio(drive)) {
|
||||
speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
|
||||
cs5535_set_drive(drive, speed);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
|
||||
|
@ -197,8 +197,8 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
|
||||
#if CY82C693_DEBUG_LOGS
|
||||
/* for debug let's show the previous values */
|
||||
|
||||
HWIF(drive)->OUTB(index, CY82_INDEX_PORT);
|
||||
data = HWIF(drive)->INB(CY82_DATA_PORT);
|
||||
outb(index, CY82_INDEX_PORT);
|
||||
data = inb(CY82_DATA_PORT);
|
||||
|
||||
printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n",
|
||||
drive->name, HWIF(drive)->channel, drive->select.b.unit,
|
||||
@ -207,8 +207,8 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
|
||||
|
||||
data = (u8)mode|(u8)(single<<2);
|
||||
|
||||
HWIF(drive)->OUTB(index, CY82_INDEX_PORT);
|
||||
HWIF(drive)->OUTB(data, CY82_DATA_PORT);
|
||||
outb(index, CY82_INDEX_PORT);
|
||||
outb(data, CY82_DATA_PORT);
|
||||
|
||||
#if CY82C693_DEBUG_INFO
|
||||
printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
|
||||
@ -227,8 +227,8 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
|
||||
*/
|
||||
|
||||
data = BUSMASTER_TIMEOUT;
|
||||
HWIF(drive)->OUTB(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
|
||||
HWIF(drive)->OUTB(data, CY82_DATA_PORT);
|
||||
outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
|
||||
outb(data, CY82_DATA_PORT);
|
||||
|
||||
#if CY82C693_DEBUG_INFO
|
||||
printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
|
||||
@ -478,21 +478,18 @@ static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
|
||||
}
|
||||
}
|
||||
|
||||
static ide_pci_device_t cy82c693_chipsets[] __devinitdata = {
|
||||
{ /* 0 */
|
||||
.name = "CY82C693",
|
||||
.init_chipset = init_chipset_cy82c693,
|
||||
.init_iops = init_iops_cy82c693,
|
||||
.init_hwif = init_hwif_cy82c693,
|
||||
.channels = 1,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = ON_BOARD,
|
||||
}
|
||||
static ide_pci_device_t cy82c693_chipset __devinitdata = {
|
||||
.name = "CY82C693",
|
||||
.init_chipset = init_chipset_cy82c693,
|
||||
.init_iops = init_iops_cy82c693,
|
||||
.init_hwif = init_hwif_cy82c693,
|
||||
.channels = 1,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = ON_BOARD,
|
||||
};
|
||||
|
||||
static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data];
|
||||
struct pci_dev *dev2;
|
||||
int ret = -ENODEV;
|
||||
|
||||
@ -501,7 +498,7 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev
|
||||
if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
|
||||
PCI_FUNC(dev->devfn) == 1) {
|
||||
dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
|
||||
ret = ide_setup_pci_devices(dev, dev2, d);
|
||||
ret = ide_setup_pci_devices(dev, dev2, &cy82c693_chipset);
|
||||
/* We leak pci refs here but thats ok - we can't be unloaded */
|
||||
}
|
||||
return ret;
|
||||
|
@ -48,19 +48,6 @@ static u8 hpt34x_ratemask (ide_drive_t *drive)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void hpt34x_clear_chipset (ide_drive_t *drive)
|
||||
{
|
||||
struct pci_dev *dev = HWIF(drive)->pci_dev;
|
||||
u32 reg1 = 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
|
||||
|
||||
pci_read_config_dword(dev, 0x44, ®1);
|
||||
pci_read_config_dword(dev, 0x48, ®2);
|
||||
tmp1 = ((0x00 << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
|
||||
tmp2 = (reg2 & ~(0x11 << drive->dn));
|
||||
pci_write_config_dword(dev, 0x44, tmp1);
|
||||
pci_write_config_dword(dev, 0x48, tmp2);
|
||||
}
|
||||
|
||||
static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
|
||||
{
|
||||
struct pci_dev *dev = HWIF(drive)->pci_dev;
|
||||
@ -81,7 +68,7 @@ static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
|
||||
pci_read_config_dword(dev, 0x44, ®1);
|
||||
pci_read_config_dword(dev, 0x48, ®2);
|
||||
tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
|
||||
tmp2 = ((hi_speed << drive->dn) | reg2);
|
||||
tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn)));
|
||||
pci_write_config_dword(dev, 0x44, tmp1);
|
||||
pci_write_config_dword(dev, 0x48, tmp2);
|
||||
|
||||
@ -99,7 +86,6 @@ static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
|
||||
static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio)
|
||||
{
|
||||
pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
|
||||
hpt34x_clear_chipset(drive);
|
||||
(void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
|
||||
}
|
||||
|
||||
@ -117,38 +103,25 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
if (!(speed))
|
||||
return 0;
|
||||
|
||||
hpt34x_clear_chipset(drive);
|
||||
(void) hpt34x_tune_chipset(drive, speed);
|
||||
return ide_dma_enable(drive);
|
||||
}
|
||||
|
||||
static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct hd_driveid *id = drive->id;
|
||||
|
||||
drive->init_speed = 0;
|
||||
|
||||
if (id && (id->capability & 1) && drive->autodma) {
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (config_chipset_for_dma(drive))
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
#ifndef CONFIG_HPT34X_AUTODMA
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
return -1;
|
||||
#else
|
||||
return hwif->ide_dma_on(drive);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
goto fast_ata_pio;
|
||||
|
||||
} else if ((id->capability & 8) || (id->field_valid & 2)) {
|
||||
fast_ata_pio:
|
||||
if (ide_use_fast_pio(drive))
|
||||
hpt34x_tune_drive(drive, 255);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -209,7 +182,6 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
|
||||
|
||||
hwif->tuneproc = &hpt34x_tune_drive;
|
||||
hwif->speedproc = &hpt34x_tune_chipset;
|
||||
hwif->no_dsc = 1;
|
||||
hwif->drives[0].autotune = 1;
|
||||
hwif->drives[1].autotune = 1;
|
||||
|
||||
|
@ -736,24 +736,15 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
|
||||
|
||||
static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
|
||||
{
|
||||
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) && config_chipset_for_dma(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
goto fast_ata_pio;
|
||||
|
||||
} else if ((id->capability & 8) || (id->field_valid & 2)) {
|
||||
fast_ata_pio:
|
||||
if (ide_use_fast_pio(drive))
|
||||
hpt3xx_tune_drive(drive, 255);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -841,7 +832,7 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dma_stat = hwif->INB(hwif->dma_status);
|
||||
dma_stat = inb(hwif->dma_status);
|
||||
/* return 1 if INTR asserted */
|
||||
if (dma_stat & 4)
|
||||
return 1;
|
||||
@ -1391,9 +1382,6 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
|
||||
u8 dma_new = 0, dma_old = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (!dmabase)
|
||||
return;
|
||||
|
||||
dma_old = hwif->INB(dmabase + 2);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
@ -244,17 +244,15 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
|
||||
static int it8213_config_drive_for_dma (ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = drive->hwif;
|
||||
u8 pio;
|
||||
|
||||
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 0;
|
||||
|
||||
hwif->speedproc(drive, XFER_PIO_0
|
||||
+ ide_get_best_pio_mode(drive, 255, 4, NULL));
|
||||
pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
|
||||
it8213_tune_chipset(drive, XFER_PIO_0 + pio);
|
||||
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -520,14 +520,12 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
|
||||
static int it821x_config_drive_for_dma (ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = drive->hwif;
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (config_chipset_for_dma(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
}
|
||||
config_it821x_chipset_for_pio(drive, 1);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -608,11 +606,11 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
|
||||
printk(".\n");
|
||||
/* Now the core code will have wrongly decided no DMA
|
||||
so we need to fix this */
|
||||
hwif->ide_dma_off_quietly(drive);
|
||||
hwif->dma_off_quietly(drive);
|
||||
#ifdef CONFIG_IDEDMA_ONLYDISK
|
||||
if (drive->media == ide_disk)
|
||||
#endif
|
||||
hwif->ide_dma_check(drive);
|
||||
ide_set_dma(drive);
|
||||
} else {
|
||||
/* Non RAID volume. Fixups to stop the core code
|
||||
doing unsupported things */
|
||||
|
@ -147,7 +147,9 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
{
|
||||
u8 speed = ide_dma_speed(drive, jmicron_ratemask(drive));
|
||||
|
||||
config_jmicron_chipset_for_pio(drive, !speed);
|
||||
if (!speed)
|
||||
return 0;
|
||||
|
||||
jmicron_tune_chipset(drive, speed);
|
||||
return ide_dma_enable(drive);
|
||||
}
|
||||
@ -162,14 +164,12 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
|
||||
static int jmicron_config_drive_for_dma (ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = drive->hwif;
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (config_chipset_for_dma(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
}
|
||||
config_jmicron_chipset_for_pio(drive, 1);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,10 +166,10 @@ static int ns87415_ide_dma_end (ide_drive_t *drive)
|
||||
/* get dma command mode */
|
||||
dma_cmd = hwif->INB(hwif->dma_command);
|
||||
/* stop DMA */
|
||||
hwif->OUTB(dma_cmd & ~1, hwif->dma_command);
|
||||
outb(dma_cmd & ~1, hwif->dma_command);
|
||||
/* from ERRATA: clear the INTR & ERROR bits */
|
||||
dma_cmd = hwif->INB(hwif->dma_command);
|
||||
hwif->OUTB(dma_cmd|6, hwif->dma_command);
|
||||
outb(dma_cmd | 6, hwif->dma_command);
|
||||
/* and free any DMA resources */
|
||||
ide_destroy_dmatable(drive);
|
||||
/* verify good DMA status */
|
||||
@ -190,7 +190,8 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive)
|
||||
static int ns87415_ide_dma_check (ide_drive_t *drive)
|
||||
{
|
||||
if (drive->media != ide_disk)
|
||||
return HWIF(drive)->ide_dma_off_quietly(drive);
|
||||
return -1;
|
||||
|
||||
return __ide_dma_check(drive);
|
||||
}
|
||||
|
||||
@ -243,9 +244,9 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
|
||||
* to SELECT_DRIVE() properly during first probe_hwif().
|
||||
*/
|
||||
timeout = 10000;
|
||||
hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
|
||||
outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
|
||||
udelay(10);
|
||||
hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
|
||||
outb(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
|
||||
do {
|
||||
udelay(50);
|
||||
stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
|
||||
@ -263,7 +264,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
|
||||
if (!hwif->dma_base)
|
||||
return;
|
||||
|
||||
hwif->OUTB(0x60, hwif->dma_status);
|
||||
outb(0x60, hwif->dma_status);
|
||||
hwif->dma_setup = &ns87415_ide_dma_setup;
|
||||
hwif->ide_dma_check = &ns87415_ide_dma_check;
|
||||
hwif->ide_dma_end = &ns87415_ide_dma_end;
|
||||
|
@ -176,34 +176,35 @@ static int cmpt_clk(int time, int bus_speed)
|
||||
return ((time*bus_speed+999)/1000);
|
||||
}
|
||||
|
||||
static void write_reg(ide_hwif_t *hwif, u8 value, int reg)
|
||||
/* Write value to register reg, base of register
|
||||
* is at reg_base (0x1f0 primary, 0x170 secondary,
|
||||
* if not changed by PCI configuration).
|
||||
* This is from setupvic.exe program.
|
||||
*/
|
||||
static void write_reg(u8 value, int reg)
|
||||
{
|
||||
hwif->INW(reg_base+1);
|
||||
hwif->INW(reg_base+1);
|
||||
hwif->OUTB(3, reg_base+2);
|
||||
hwif->OUTB(value, reg_base+reg);
|
||||
hwif->OUTB(0x83, reg_base+2);
|
||||
inw(reg_base + 1);
|
||||
inw(reg_base + 1);
|
||||
outb(3, reg_base + 2);
|
||||
outb(value, reg_base + reg);
|
||||
outb(0x83, reg_base + 2);
|
||||
}
|
||||
|
||||
static u8 read_reg(ide_hwif_t *hwif, int reg)
|
||||
/* Read value from register reg, base of register
|
||||
* is at reg_base (0x1f0 primary, 0x170 secondary,
|
||||
* if not changed by PCI configuration).
|
||||
* This is from setupvic.exe program.
|
||||
*/
|
||||
static u8 read_reg(int reg)
|
||||
{
|
||||
u8 ret = 0;
|
||||
|
||||
hwif->INW(reg_base+1);
|
||||
hwif->INW(reg_base+1);
|
||||
hwif->OUTB(3, reg_base+2);
|
||||
ret = hwif->INB(reg_base+reg);
|
||||
hwif->OUTB(0x83, reg_base+2);
|
||||
inw(reg_base + 1);
|
||||
inw(reg_base + 1);
|
||||
outb(3, reg_base + 2);
|
||||
ret = inb(reg_base + reg);
|
||||
outb(0x83, reg_base + 2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -286,39 +287,39 @@ static void opti621_tune_drive (ide_drive_t *drive, u8 pio)
|
||||
reg_base = hwif->io_ports[IDE_DATA_OFFSET];
|
||||
|
||||
/* allow Register-B */
|
||||
hwif->OUTB(0xc0, reg_base+CNTRL_REG);
|
||||
outb(0xc0, reg_base + CNTRL_REG);
|
||||
/* hmm, setupvic.exe does this ;-) */
|
||||
hwif->OUTB(0xff, reg_base+5);
|
||||
outb(0xff, reg_base + 5);
|
||||
/* if reads 0xff, adapter not exist? */
|
||||
(void) hwif->INB(reg_base+CNTRL_REG);
|
||||
(void)inb(reg_base + CNTRL_REG);
|
||||
/* if reads 0xc0, no interface exist? */
|
||||
read_reg(hwif, CNTRL_REG);
|
||||
read_reg(CNTRL_REG);
|
||||
/* read version, probably 0 */
|
||||
read_reg(hwif, STRAP_REG);
|
||||
read_reg(STRAP_REG);
|
||||
|
||||
/* program primary drive */
|
||||
/* select Index-0 for Register-A */
|
||||
write_reg(hwif, 0, MISC_REG);
|
||||
/* set read cycle timings */
|
||||
write_reg(hwif, cycle1, READ_REG);
|
||||
/* set write cycle timings */
|
||||
write_reg(hwif, cycle1, WRITE_REG);
|
||||
/* select Index-0 for Register-A */
|
||||
write_reg(0, MISC_REG);
|
||||
/* set read cycle timings */
|
||||
write_reg(cycle1, READ_REG);
|
||||
/* set write cycle timings */
|
||||
write_reg(cycle1, WRITE_REG);
|
||||
|
||||
/* program secondary drive */
|
||||
/* select Index-1 for Register-B */
|
||||
write_reg(hwif, 1, MISC_REG);
|
||||
/* set read cycle timings */
|
||||
write_reg(hwif, cycle2, READ_REG);
|
||||
/* set write cycle timings */
|
||||
write_reg(hwif, cycle2, WRITE_REG);
|
||||
/* select Index-1 for Register-B */
|
||||
write_reg(1, MISC_REG);
|
||||
/* set read cycle timings */
|
||||
write_reg(cycle2, READ_REG);
|
||||
/* set write cycle timings */
|
||||
write_reg(cycle2, WRITE_REG);
|
||||
|
||||
/* use Register-A for drive 0 */
|
||||
/* use Register-B for drive 1 */
|
||||
write_reg(hwif, 0x85, CNTRL_REG);
|
||||
write_reg(0x85, CNTRL_REG);
|
||||
|
||||
/* set address setup, DRDY timings, */
|
||||
/* and read prefetch for both drives */
|
||||
write_reg(hwif, misc, MISC_REG);
|
||||
write_reg(misc, MISC_REG);
|
||||
|
||||
spin_unlock_irqrestore(&ide_lock, flags);
|
||||
}
|
||||
|
@ -101,8 +101,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index)
|
||||
{
|
||||
u8 value;
|
||||
|
||||
hwif->OUTB(index, hwif->dma_vendor1);
|
||||
value = hwif->INB(hwif->dma_vendor3);
|
||||
outb(index, hwif->dma_vendor1);
|
||||
value = inb(hwif->dma_vendor3);
|
||||
|
||||
DBG("index[%02X] value[%02X]\n", index, value);
|
||||
return value;
|
||||
@ -115,8 +115,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index)
|
||||
*/
|
||||
static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value)
|
||||
{
|
||||
hwif->OUTB(index, hwif->dma_vendor1);
|
||||
hwif->OUTB(value, hwif->dma_vendor3);
|
||||
outb(index, hwif->dma_vendor1);
|
||||
outb(value, hwif->dma_vendor3);
|
||||
DBG("index[%02X] value[%02X]\n", index, value);
|
||||
}
|
||||
|
||||
@ -281,25 +281,15 @@ static int config_chipset_for_dma(ide_drive_t *drive)
|
||||
|
||||
static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
|
||||
{
|
||||
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) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
if (ide_use_fast_pio(drive))
|
||||
pdcnew_tune_drive(drive, 255);
|
||||
|
||||
goto fast_ata_pio;
|
||||
|
||||
} else if ((id->capability & 8) || (id->field_valid & 2)) {
|
||||
fast_ata_pio:
|
||||
hwif->tuneproc(drive, 255);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int pdcnew_quirkproc(ide_drive_t *drive)
|
||||
|
@ -2,6 +2,7 @@
|
||||
* linux/drivers/ide/pci/pdc202xx_old.c Version 0.36 Sept 11, 2002
|
||||
*
|
||||
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
|
||||
* Copyright (C) 2006-2007 MontaVista Software, Inc.
|
||||
*
|
||||
* Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
|
||||
* compiled into the kernel if you have more than one card installed.
|
||||
@ -216,21 +217,10 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
|
||||
}
|
||||
|
||||
|
||||
/* 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 config_chipset_for_pio (ide_drive_t *drive, u8 pio)
|
||||
static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio)
|
||||
{
|
||||
u8 speed = 0;
|
||||
|
||||
if (pio == 5) pio = 4;
|
||||
speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
|
||||
|
||||
pdc202xx_tune_chipset(drive, speed);
|
||||
pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
|
||||
pdc202xx_tune_chipset(drive, XFER_PIO_0 + pio);
|
||||
}
|
||||
|
||||
static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
|
||||
@ -250,17 +240,17 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
|
||||
static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
|
||||
{
|
||||
unsigned long clock_reg = hwif->dma_master + 0x11;
|
||||
u8 clock = hwif->INB(clock_reg);
|
||||
u8 clock = inb(clock_reg);
|
||||
|
||||
hwif->OUTB(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
|
||||
outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
|
||||
}
|
||||
|
||||
static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
|
||||
{
|
||||
unsigned long clock_reg = hwif->dma_master + 0x11;
|
||||
u8 clock = hwif->INB(clock_reg);
|
||||
u8 clock = inb(clock_reg);
|
||||
|
||||
hwif->OUTB(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
|
||||
outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
|
||||
}
|
||||
|
||||
static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
@ -332,27 +322,15 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
|
||||
static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct hd_driveid *id = drive->id;
|
||||
|
||||
drive->init_speed = 0;
|
||||
|
||||
if (id && (id->capability & 1) && drive->autodma) {
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (config_chipset_for_dma(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
}
|
||||
if (ide_use_fast_pio(drive))
|
||||
pdc202xx_tune_drive(drive, 255);
|
||||
|
||||
goto fast_ata_pio;
|
||||
|
||||
} else if ((id->capability & 8) || (id->field_valid & 2)) {
|
||||
fast_ata_pio:
|
||||
hwif->tuneproc(drive, 5);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int pdc202xx_quirkproc (ide_drive_t *drive)
|
||||
@ -375,14 +353,14 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
|
||||
unsigned long high_16 = hwif->dma_master;
|
||||
unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
|
||||
u32 word_count = 0;
|
||||
u8 clock = hwif->INB(high_16 + 0x11);
|
||||
u8 clock = inb(high_16 + 0x11);
|
||||
|
||||
hwif->OUTB(clock|(hwif->channel ? 0x08 : 0x02), high_16+0x11);
|
||||
outb(clock | (hwif->channel ? 0x08 : 0x02), high_16 + 0x11);
|
||||
word_count = (rq->nr_sectors << 8);
|
||||
word_count = (rq_data_dir(rq) == READ) ?
|
||||
word_count | 0x05000000 :
|
||||
word_count | 0x06000000;
|
||||
hwif->OUTL(word_count, atapi_reg);
|
||||
outl(word_count, atapi_reg);
|
||||
}
|
||||
ide_dma_start(drive);
|
||||
}
|
||||
@ -395,9 +373,9 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
|
||||
unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
|
||||
u8 clock = 0;
|
||||
|
||||
hwif->OUTL(0, atapi_reg); /* zero out extra */
|
||||
clock = hwif->INB(high_16 + 0x11);
|
||||
hwif->OUTB(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11);
|
||||
outl(0, atapi_reg); /* zero out extra */
|
||||
clock = inb(high_16 + 0x11);
|
||||
outb(clock & ~(hwif->channel ? 0x08:0x02), high_16 + 0x11);
|
||||
}
|
||||
if (drive->current_speed > XFER_UDMA_2)
|
||||
pdc_old_disable_66MHz_clock(drive->hwif);
|
||||
@ -408,8 +386,8 @@ static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
unsigned long high_16 = hwif->dma_master;
|
||||
u8 dma_stat = hwif->INB(hwif->dma_status);
|
||||
u8 sc1d = hwif->INB((high_16 + 0x001d));
|
||||
u8 dma_stat = inb(hwif->dma_status);
|
||||
u8 sc1d = inb(high_16 + 0x001d);
|
||||
|
||||
if (hwif->channel) {
|
||||
/* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */
|
||||
@ -445,11 +423,11 @@ static int pdc202xx_ide_dma_timeout(ide_drive_t *drive)
|
||||
static void pdc202xx_reset_host (ide_hwif_t *hwif)
|
||||
{
|
||||
unsigned long high_16 = hwif->dma_master;
|
||||
u8 udma_speed_flag = hwif->INB(high_16|0x001f);
|
||||
u8 udma_speed_flag = inb(high_16 | 0x001f);
|
||||
|
||||
hwif->OUTB((udma_speed_flag | 0x10), (high_16|0x001f));
|
||||
outb(udma_speed_flag | 0x10, high_16 | 0x001f);
|
||||
mdelay(100);
|
||||
hwif->OUTB((udma_speed_flag & ~0x10), (high_16|0x001f));
|
||||
outb(udma_speed_flag & ~0x10, high_16 | 0x001f);
|
||||
mdelay(2000); /* 2 seconds ?! */
|
||||
|
||||
printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
|
||||
@ -463,7 +441,7 @@ static void pdc202xx_reset (ide_drive_t *drive)
|
||||
|
||||
pdc202xx_reset_host(hwif);
|
||||
pdc202xx_reset_host(mate);
|
||||
hwif->tuneproc(drive, 5);
|
||||
pdc202xx_tune_drive(drive, 255);
|
||||
}
|
||||
|
||||
static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
|
||||
@ -490,7 +468,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
|
||||
hwif->rqsize = 256;
|
||||
|
||||
hwif->autodma = 0;
|
||||
hwif->tuneproc = &config_chipset_for_pio;
|
||||
hwif->tuneproc = &pdc202xx_tune_drive;
|
||||
hwif->quirkproc = &pdc202xx_quirkproc;
|
||||
|
||||
if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
|
||||
@ -537,9 +515,9 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
|
||||
return;
|
||||
}
|
||||
|
||||
udma_speed_flag = hwif->INB((dmabase|0x1f));
|
||||
primary_mode = hwif->INB((dmabase|0x1a));
|
||||
secondary_mode = hwif->INB((dmabase|0x1b));
|
||||
udma_speed_flag = inb(dmabase | 0x1f);
|
||||
primary_mode = inb(dmabase | 0x1a);
|
||||
secondary_mode = inb(dmabase | 0x1b);
|
||||
printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \
|
||||
"Primary %s Mode " \
|
||||
"Secondary %s Mode.\n", hwif->cds->name,
|
||||
@ -552,30 +530,10 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
|
||||
printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ",
|
||||
hwif->cds->name, udma_speed_flag,
|
||||
(udma_speed_flag|1));
|
||||
hwif->OUTB(udma_speed_flag|1,(dmabase|0x1f));
|
||||
printk("%sACTIVE\n",
|
||||
(hwif->INB(dmabase|0x1f)&1) ? "":"IN");
|
||||
outb(udma_speed_flag | 1, dmabase | 0x1f);
|
||||
printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
|
||||
}
|
||||
#endif /* CONFIG_PDC202XX_BURST */
|
||||
#ifdef CONFIG_PDC202XX_MASTER
|
||||
if (!(primary_mode & 1)) {
|
||||
printk(KERN_INFO "%s: FORCING PRIMARY MODE BIT "
|
||||
"0x%02x -> 0x%02x ", hwif->cds->name,
|
||||
primary_mode, (primary_mode|1));
|
||||
hwif->OUTB(primary_mode|1, (dmabase|0x1a));
|
||||
printk("%s\n",
|
||||
(hwif->INB((dmabase|0x1a)) & 1) ? "MASTER" : "PCI");
|
||||
}
|
||||
|
||||
if (!(secondary_mode & 1)) {
|
||||
printk(KERN_INFO "%s: FORCING SECONDARY MODE BIT "
|
||||
"0x%02x -> 0x%02x ", hwif->cds->name,
|
||||
secondary_mode, (secondary_mode|1));
|
||||
hwif->OUTB(secondary_mode|1, (dmabase|0x1b));
|
||||
printk("%s\n",
|
||||
(hwif->INB((dmabase|0x1b)) & 1) ? "MASTER" : "PCI");
|
||||
}
|
||||
#endif /* CONFIG_PDC202XX_MASTER */
|
||||
|
||||
ide_setup_dma(hwif, dmabase, 8);
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ static int piix_config_drive_for_dma (ide_drive_t *drive)
|
||||
* If no DMA speed was available or the chipset has DMA bugs
|
||||
* then disable DMA and use PIO
|
||||
*/
|
||||
if (!speed || no_piix_dma)
|
||||
if (!speed)
|
||||
return 0;
|
||||
|
||||
(void) piix_tune_chipset(drive, speed);
|
||||
@ -386,41 +386,28 @@ static int piix_config_drive_for_dma (ide_drive_t *drive)
|
||||
|
||||
static int piix_config_drive_xfer_rate (ide_drive_t *drive)
|
||||
{
|
||||
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) && piix_config_drive_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_dma(drive) && piix_config_drive_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:
|
||||
if (ide_use_fast_pio(drive))
|
||||
/* Find best PIO mode. */
|
||||
(void) hwif->speedproc(drive, XFER_PIO_0 +
|
||||
ide_get_best_pio_mode(drive, 255, 4, NULL));
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
piix_tune_chipset(drive, XFER_PIO_0 +
|
||||
ide_get_best_pio_mode(drive, 255, 4, NULL));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* init_chipset_piix - set up the PIIX chipset
|
||||
* @dev: PCI device to set up
|
||||
* @name: Name of the device
|
||||
* piix_is_ichx - check if ICHx
|
||||
* @dev: PCI device to check
|
||||
*
|
||||
* Initialize the PCI device as required. For the PIIX this turns
|
||||
* out to be nice and simple
|
||||
* returns 1 if ICHx, 0 otherwise.
|
||||
*/
|
||||
|
||||
static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
|
||||
static int piix_is_ichx(struct pci_dev *dev)
|
||||
{
|
||||
switch(dev->device) {
|
||||
switch (dev->device) {
|
||||
case PCI_DEVICE_ID_INTEL_82801EB_1:
|
||||
case PCI_DEVICE_ID_INTEL_82801AA_1:
|
||||
case PCI_DEVICE_ID_INTEL_82801AB_1:
|
||||
@ -438,18 +425,60 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char
|
||||
case PCI_DEVICE_ID_INTEL_ICH7_21:
|
||||
case PCI_DEVICE_ID_INTEL_ESB2_18:
|
||||
case PCI_DEVICE_ID_INTEL_ICH8_6:
|
||||
{
|
||||
unsigned int extra = 0;
|
||||
pci_read_config_dword(dev, 0x54, &extra);
|
||||
pci_write_config_dword(dev, 0x54, extra|0x400);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* init_chipset_piix - set up the PIIX chipset
|
||||
* @dev: PCI device to set up
|
||||
* @name: Name of the device
|
||||
*
|
||||
* Initialize the PCI device as required. For the PIIX this turns
|
||||
* out to be nice and simple
|
||||
*/
|
||||
|
||||
static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
|
||||
{
|
||||
if (piix_is_ichx(dev)) {
|
||||
unsigned int extra = 0;
|
||||
pci_read_config_dword(dev, 0x54, &extra);
|
||||
pci_write_config_dword(dev, 0x54, extra|0x400);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* piix_dma_clear_irq - clear BMDMA status
|
||||
* @drive: IDE drive to clear
|
||||
*
|
||||
* Called from ide_intr() for PIO interrupts
|
||||
* to clear BMDMA status as needed by ICHx
|
||||
*/
|
||||
static void piix_dma_clear_irq(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
u8 dma_stat;
|
||||
|
||||
/* clear the INTR & ERROR bits */
|
||||
dma_stat = hwif->INB(hwif->dma_status);
|
||||
/* Should we force the bit as well ? */
|
||||
hwif->OUTB(dma_stat, hwif->dma_status);
|
||||
}
|
||||
|
||||
static int __devinit piix_cable_detect(ide_hwif_t *hwif)
|
||||
{
|
||||
struct pci_dev *dev = hwif->pci_dev;
|
||||
u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30;
|
||||
|
||||
pci_read_config_byte(dev, 0x54, ®54h);
|
||||
|
||||
return (reg54h & mask) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* init_hwif_piix - fill in the hwif for the PIIX
|
||||
* @hwif: IDE interface
|
||||
@ -460,9 +489,6 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char
|
||||
|
||||
static void __devinit init_hwif_piix(ide_hwif_t *hwif)
|
||||
{
|
||||
u8 reg54h = 0, reg55h = 0, ata66 = 0;
|
||||
u8 mask = hwif->channel ? 0xc0 : 0x30;
|
||||
|
||||
#ifndef CONFIG_IA64
|
||||
if (!hwif->irq)
|
||||
hwif->irq = hwif->channel ? 15 : 14;
|
||||
@ -472,10 +498,6 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
|
||||
/* This is a painful system best to let it self tune for now */
|
||||
return;
|
||||
}
|
||||
/* ESB2 appears to generate spurious DMA interrupts in PIO mode
|
||||
when in native mode */
|
||||
if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_ESB2_18)
|
||||
hwif->atapi_irq_bogon = 1;
|
||||
|
||||
hwif->autodma = 0;
|
||||
hwif->tuneproc = &piix_tune_drive;
|
||||
@ -486,15 +508,16 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
|
||||
if (!hwif->dma_base)
|
||||
return;
|
||||
|
||||
/* ICHx need to clear the bmdma status for all interrupts */
|
||||
if (piix_is_ichx(hwif->pci_dev))
|
||||
hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
|
||||
|
||||
hwif->atapi_dma = 1;
|
||||
hwif->ultra_mask = 0x3f;
|
||||
hwif->mwdma_mask = 0x06;
|
||||
hwif->swdma_mask = 0x04;
|
||||
|
||||
switch(hwif->pci_dev->device) {
|
||||
case PCI_DEVICE_ID_INTEL_82371MX:
|
||||
hwif->mwdma_mask = 0x80;
|
||||
hwif->swdma_mask = 0x80;
|
||||
case PCI_DEVICE_ID_INTEL_82371FB_0:
|
||||
case PCI_DEVICE_ID_INTEL_82371FB_1:
|
||||
case PCI_DEVICE_ID_INTEL_82371SB_1:
|
||||
@ -507,14 +530,14 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
|
||||
hwif->ultra_mask = 0x07;
|
||||
break;
|
||||
default:
|
||||
pci_read_config_byte(hwif->pci_dev, 0x54, ®54h);
|
||||
pci_read_config_byte(hwif->pci_dev, 0x55, ®55h);
|
||||
ata66 = (reg54h & mask) ? 1 : 0;
|
||||
if (!hwif->udma_four)
|
||||
hwif->udma_four = piix_cable_detect(hwif);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(hwif->udma_four))
|
||||
hwif->udma_four = ata66;
|
||||
if (no_piix_dma)
|
||||
hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0;
|
||||
|
||||
hwif->ide_dma_check = &piix_config_drive_xfer_rate;
|
||||
if (!noautodma)
|
||||
hwif->autodma = 1;
|
||||
|
@ -161,7 +161,7 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode)
|
||||
/*
|
||||
* Default to DMA-off in case we run into trouble here.
|
||||
*/
|
||||
hwif->ide_dma_off_quietly(drive); /* turn off DMA while we fiddle */
|
||||
hwif->dma_off_quietly(drive); /* turn off DMA while we fiddle */
|
||||
outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */
|
||||
|
||||
/*
|
||||
@ -241,10 +241,7 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode)
|
||||
|
||||
outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */
|
||||
|
||||
/*
|
||||
* Finally, turn DMA on in software, and exit.
|
||||
*/
|
||||
return hwif->ide_dma_on(drive); /* success */
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -442,10 +439,10 @@ static int sc1200_resume (struct pci_dev *dev)
|
||||
ide_drive_t *drive = &(hwif->drives[d]);
|
||||
if (drive->present && !__ide_dma_bad_drive(drive)) {
|
||||
int was_using_dma = drive->using_dma;
|
||||
hwif->ide_dma_off_quietly(drive);
|
||||
hwif->dma_off_quietly(drive);
|
||||
sc1200_config_dma(drive);
|
||||
if (!was_using_dma && drive->using_dma) {
|
||||
hwif->ide_dma_off_quietly(drive);
|
||||
hwif->dma_off_quietly(drive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
|
||||
if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
|
||||
(dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
|
||||
if (!drive->init_speed) {
|
||||
u8 dma_stat = hwif->INB(hwif->dma_status);
|
||||
u8 dma_stat = inb(hwif->dma_status);
|
||||
|
||||
dma_pio:
|
||||
if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
|
||||
@ -315,35 +315,15 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
|
||||
static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
|
||||
{
|
||||
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) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (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:
|
||||
if (ide_use_fast_pio(drive))
|
||||
config_chipset_for_pio(drive);
|
||||
// hwif->tuneproc(drive, 5);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This can go soon */
|
||||
|
||||
static int svwks_ide_dma_end (ide_drive_t *drive)
|
||||
{
|
||||
return __ide_dma_end(drive);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name)
|
||||
@ -537,35 +517,20 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
|
||||
}
|
||||
|
||||
hwif->ide_dma_check = &svwks_config_drive_xfer_rate;
|
||||
if (hwif->pci_dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE)
|
||||
hwif->ide_dma_end = &svwks_ide_dma_end;
|
||||
else if (!(hwif->udma_four))
|
||||
hwif->udma_four = ata66_svwks(hwif);
|
||||
if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
|
||||
if (!hwif->udma_four)
|
||||
hwif->udma_four = ata66_svwks(hwif);
|
||||
}
|
||||
if (!noautodma)
|
||||
hwif->autodma = 1;
|
||||
|
||||
dma_stat = hwif->INB(hwif->dma_status);
|
||||
dma_stat = inb(hwif->dma_status);
|
||||
hwif->drives[0].autodma = (dma_stat & 0x20);
|
||||
hwif->drives[1].autodma = (dma_stat & 0x40);
|
||||
hwif->drives[0].autotune = (!(dma_stat & 0x20));
|
||||
hwif->drives[1].autotune = (!(dma_stat & 0x40));
|
||||
}
|
||||
|
||||
/*
|
||||
* We allow the BM-DMA driver to only work on enabled interfaces.
|
||||
*/
|
||||
static void __devinit init_dma_svwks (ide_hwif_t *hwif, unsigned long dmabase)
|
||||
{
|
||||
struct pci_dev *dev = hwif->pci_dev;
|
||||
|
||||
if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
|
||||
(dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
|
||||
(!(PCI_FUNC(dev->devfn) & 1)) && (hwif->channel))
|
||||
return;
|
||||
|
||||
ide_setup_dma(hwif, dmabase, 8);
|
||||
}
|
||||
|
||||
static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)
|
||||
{
|
||||
return ide_setup_pci_device(dev, d);
|
||||
@ -600,7 +565,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
|
||||
.init_setup = init_setup_svwks,
|
||||
.init_chipset = init_chipset_svwks,
|
||||
.init_hwif = init_hwif_svwks,
|
||||
.init_dma = init_dma_svwks,
|
||||
.channels = 2,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = ON_BOARD,
|
||||
@ -609,7 +573,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
|
||||
.init_setup = init_setup_csb6,
|
||||
.init_chipset = init_chipset_svwks,
|
||||
.init_hwif = init_hwif_svwks,
|
||||
.init_dma = init_dma_svwks,
|
||||
.channels = 2,
|
||||
.autodma = AUTODMA,
|
||||
.bootable = ON_BOARD,
|
||||
@ -618,7 +581,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
|
||||
.init_setup = init_setup_csb6,
|
||||
.init_chipset = init_chipset_svwks,
|
||||
.init_hwif = init_hwif_svwks,
|
||||
.init_dma = init_dma_svwks,
|
||||
.channels = 1, /* 2 */
|
||||
.autodma = AUTODMA,
|
||||
.bootable = ON_BOARD,
|
||||
@ -627,7 +589,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
|
||||
.init_setup = init_setup_svwks,
|
||||
.init_chipset = init_chipset_svwks,
|
||||
.init_hwif = init_hwif_svwks,
|
||||
.init_dma = init_dma_svwks,
|
||||
.channels = 1, /* 2 */
|
||||
.autodma = AUTODMA,
|
||||
.bootable = ON_BOARD,
|
||||
|
@ -110,24 +110,24 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
|
||||
static void
|
||||
sgiioc4_maskproc(ide_drive_t * drive, int mask)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
|
||||
IDE_CONTROL_REG);
|
||||
writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
|
||||
(void __iomem *)IDE_CONTROL_REG);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sgiioc4_checkirq(ide_hwif_t * hwif)
|
||||
{
|
||||
u8 intr_reg =
|
||||
hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4);
|
||||
unsigned long intr_addr =
|
||||
hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4;
|
||||
|
||||
if (intr_reg & 0x03)
|
||||
if ((u8)readl((void __iomem *)intr_addr) & 0x03)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 sgiioc4_INB(unsigned long);
|
||||
|
||||
static int
|
||||
sgiioc4_clearirq(ide_drive_t * drive)
|
||||
@ -138,21 +138,21 @@ sgiioc4_clearirq(ide_drive_t * drive)
|
||||
hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2);
|
||||
|
||||
/* Code to check for PCI error conditions */
|
||||
intr_reg = hwif->INL(other_ir);
|
||||
intr_reg = readl((void __iomem *)other_ir);
|
||||
if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */
|
||||
/*
|
||||
* Using hwif->INB to read the IDE_STATUS_REG has a side effect
|
||||
* Using sgiioc4_INB to read the IDE_STATUS_REG has a side effect
|
||||
* of clearing the interrupt. The first read should clear it
|
||||
* if it is set. The second read should return a "clear" status
|
||||
* if it got cleared. If not, then spin for a bit trying to
|
||||
* clear it.
|
||||
*/
|
||||
u8 stat = hwif->INB(IDE_STATUS_REG);
|
||||
u8 stat = sgiioc4_INB(IDE_STATUS_REG);
|
||||
int count = 0;
|
||||
stat = hwif->INB(IDE_STATUS_REG);
|
||||
stat = sgiioc4_INB(IDE_STATUS_REG);
|
||||
while ((stat & 0x80) && (count++ < 100)) {
|
||||
udelay(1);
|
||||
stat = hwif->INB(IDE_STATUS_REG);
|
||||
stat = sgiioc4_INB(IDE_STATUS_REG);
|
||||
}
|
||||
|
||||
if (intr_reg & 0x02) {
|
||||
@ -161,9 +161,9 @@ sgiioc4_clearirq(ide_drive_t * drive)
|
||||
pci_stat_cmd_reg;
|
||||
|
||||
pci_err_addr_low =
|
||||
hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET]);
|
||||
readl((void __iomem *)hwif->io_ports[IDE_IRQ_OFFSET]);
|
||||
pci_err_addr_high =
|
||||
hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + 4);
|
||||
readl((void __iomem *)(hwif->io_ports[IDE_IRQ_OFFSET] + 4));
|
||||
pci_read_config_dword(hwif->pci_dev, PCI_COMMAND,
|
||||
&pci_stat_cmd_reg);
|
||||
printk(KERN_ERR
|
||||
@ -180,9 +180,9 @@ sgiioc4_clearirq(ide_drive_t * drive)
|
||||
}
|
||||
|
||||
/* Clear the Interrupt, Error bits on the IOC4 */
|
||||
hwif->OUTL(0x03, other_ir);
|
||||
writel(0x03, (void __iomem *)other_ir);
|
||||
|
||||
intr_reg = hwif->INL(other_ir);
|
||||
intr_reg = readl((void __iomem *)other_ir);
|
||||
}
|
||||
|
||||
return intr_reg & 3;
|
||||
@ -191,23 +191,25 @@ sgiioc4_clearirq(ide_drive_t * drive)
|
||||
static void sgiioc4_ide_dma_start(ide_drive_t * drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4);
|
||||
unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4;
|
||||
unsigned int reg = readl((void __iomem *)ioc4_dma_addr);
|
||||
unsigned int temp_reg = reg | IOC4_S_DMA_START;
|
||||
|
||||
hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4);
|
||||
writel(temp_reg, (void __iomem *)ioc4_dma_addr);
|
||||
}
|
||||
|
||||
static u32
|
||||
sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
|
||||
{
|
||||
unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
|
||||
u32 ioc4_dma;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
|
||||
ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
|
||||
while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) {
|
||||
udelay(1);
|
||||
ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
|
||||
ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
|
||||
}
|
||||
return ioc4_dma;
|
||||
}
|
||||
@ -218,11 +220,11 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
|
||||
{
|
||||
u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
u64 dma_base = hwif->dma_base;
|
||||
unsigned long dma_base = hwif->dma_base;
|
||||
int dma_stat = 0;
|
||||
unsigned long *ending_dma = ide_get_hwifdata(hwif);
|
||||
|
||||
hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
|
||||
writel(IOC4_S_DMA_STOP, (void __iomem *)(dma_base + IOC4_DMA_CTRL * 4));
|
||||
|
||||
ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
|
||||
|
||||
@ -254,8 +256,8 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
|
||||
dma_stat = 1;
|
||||
}
|
||||
|
||||
bc_dev = hwif->INL(dma_base + IOC4_BC_DEV * 4);
|
||||
bc_mem = hwif->INL(dma_base + IOC4_BC_MEM * 4);
|
||||
bc_dev = readl((void __iomem *)(dma_base + IOC4_BC_DEV * 4));
|
||||
bc_mem = readl((void __iomem *)(dma_base + IOC4_BC_MEM * 4));
|
||||
|
||||
if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) {
|
||||
if (bc_dev > bc_mem + 8) {
|
||||
@ -272,35 +274,30 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
|
||||
return dma_stat;
|
||||
}
|
||||
|
||||
static int
|
||||
sgiioc4_ide_dma_check(ide_drive_t * drive)
|
||||
{
|
||||
if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
|
||||
printk(KERN_INFO
|
||||
"Couldnot set %s in Multimode-2 DMA mode | "
|
||||
"Drive %s using PIO instead\n",
|
||||
drive->name, drive->name);
|
||||
drive->using_dma = 0;
|
||||
} else
|
||||
drive->using_dma = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sgiioc4_ide_dma_on(ide_drive_t * drive)
|
||||
{
|
||||
drive->using_dma = 1;
|
||||
|
||||
return HWIF(drive)->ide_dma_host_on(drive);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sgiioc4_ide_dma_off_quietly(ide_drive_t * drive)
|
||||
static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
|
||||
{
|
||||
drive->using_dma = 0;
|
||||
|
||||
return HWIF(drive)->ide_dma_host_off(drive);
|
||||
drive->hwif->dma_host_off(drive);
|
||||
}
|
||||
|
||||
static int sgiioc4_ide_dma_check(ide_drive_t *drive)
|
||||
{
|
||||
/* FIXME: check for available DMA modes */
|
||||
if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
|
||||
printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
|
||||
"using PIO instead\n", drive->name);
|
||||
return -1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns 1 if dma irq issued, 0 otherwise */
|
||||
@ -310,21 +307,13 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
|
||||
return sgiioc4_checkirq(HWIF(drive));
|
||||
}
|
||||
|
||||
static int
|
||||
sgiioc4_ide_dma_host_on(ide_drive_t * drive)
|
||||
static void sgiioc4_dma_host_on(ide_drive_t * drive)
|
||||
{
|
||||
if (drive->using_dma)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
sgiioc4_ide_dma_host_off(ide_drive_t * drive)
|
||||
static void sgiioc4_dma_host_off(ide_drive_t * drive)
|
||||
{
|
||||
sgiioc4_clearirq(drive);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -436,16 +425,17 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
|
||||
{
|
||||
u32 ioc4_dma;
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
u64 dma_base = hwif->dma_base;
|
||||
unsigned long dma_base = hwif->dma_base;
|
||||
unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
|
||||
u32 dma_addr, ending_dma_addr;
|
||||
|
||||
ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
|
||||
ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
|
||||
|
||||
if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
|
||||
printk(KERN_WARNING
|
||||
"%s(%s):Warning!! DMA from previous transfer was still active\n",
|
||||
__FUNCTION__, drive->name);
|
||||
hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
|
||||
writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
|
||||
ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
|
||||
|
||||
if (ioc4_dma & IOC4_S_DMA_STOP)
|
||||
@ -454,13 +444,13 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
|
||||
__FUNCTION__, drive->name);
|
||||
}
|
||||
|
||||
ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
|
||||
ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
|
||||
if (ioc4_dma & IOC4_S_DMA_ERROR) {
|
||||
printk(KERN_WARNING
|
||||
"%s(%s) : Warning!! - DMA Error during Previous"
|
||||
" transfer | status 0x%x\n",
|
||||
__FUNCTION__, drive->name, ioc4_dma);
|
||||
hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
|
||||
writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
|
||||
ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
|
||||
|
||||
if (ioc4_dma & IOC4_S_DMA_STOP)
|
||||
@ -471,14 +461,14 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
|
||||
|
||||
/* Address of the Scatter Gather List */
|
||||
dma_addr = cpu_to_le32(hwif->dmatable_dma);
|
||||
hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4);
|
||||
writel(dma_addr, (void __iomem *)(dma_base + IOC4_DMA_PTR_L * 4));
|
||||
|
||||
/* Address of the Ending DMA */
|
||||
memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
|
||||
ending_dma_addr = cpu_to_le32(hwif->dma_status);
|
||||
hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4);
|
||||
writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
|
||||
|
||||
hwif->OUTL(dma_direction, dma_base + IOC4_DMA_CTRL * 4);
|
||||
writel(dma_direction, (void __iomem *)ioc4_dma_addr);
|
||||
drive->waiting_for_dma = 1;
|
||||
}
|
||||
|
||||
@ -590,7 +580,7 @@ static int sgiioc4_ide_dma_setup(ide_drive_t *drive)
|
||||
static void __devinit
|
||||
ide_init_sgiioc4(ide_hwif_t * hwif)
|
||||
{
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
hwif->autodma = 1;
|
||||
hwif->atapi_dma = 1;
|
||||
hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
|
||||
@ -613,10 +603,10 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
|
||||
hwif->ide_dma_end = &sgiioc4_ide_dma_end;
|
||||
hwif->ide_dma_check = &sgiioc4_ide_dma_check;
|
||||
hwif->ide_dma_on = &sgiioc4_ide_dma_on;
|
||||
hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly;
|
||||
hwif->dma_off_quietly = &sgiioc4_dma_off_quietly;
|
||||
hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
|
||||
hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
|
||||
hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
|
||||
hwif->dma_host_on = &sgiioc4_dma_host_on;
|
||||
hwif->dma_host_off = &sgiioc4_dma_host_off;
|
||||
hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
|
||||
hwif->ide_dma_timeout = &__ide_dma_timeout;
|
||||
|
||||
@ -688,7 +678,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
|
||||
default_hwif_mmiops(hwif);
|
||||
|
||||
/* Initializing chipset IRQ Registers */
|
||||
hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4);
|
||||
writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
|
||||
|
||||
ide_init_sgiioc4(hwif);
|
||||
|
||||
@ -729,8 +719,7 @@ pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
|
||||
{
|
||||
static ide_pci_device_t sgiioc4_chipset __devinitdata = {
|
||||
/* Channel 0 */
|
||||
.name = "SGIIOC4",
|
||||
.init_hwif = ide_init_sgiioc4,
|
||||
@ -739,7 +728,6 @@ static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
|
||||
.autodma = AUTODMA,
|
||||
/* SGI IOC4 doesn't have enablebits. */
|
||||
.bootable = ON_BOARD,
|
||||
}
|
||||
};
|
||||
|
||||
int
|
||||
@ -751,8 +739,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd)
|
||||
if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
|
||||
return 0;
|
||||
|
||||
return pci_init_sgiioc4(idd->idd_pdev,
|
||||
&sgiioc4_chipsets[idd->idd_pci_id->driver_data]);
|
||||
return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipset);
|
||||
}
|
||||
|
||||
static struct ioc4_submodule ioc4_ide_submodule = {
|
||||
|
@ -1,8 +1,9 @@
|
||||
/*
|
||||
* linux/drivers/ide/pci/siimage.c Version 1.07 Nov 30, 2003
|
||||
* linux/drivers/ide/pci/siimage.c Version 1.11 Jan 27, 2007
|
||||
*
|
||||
* Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
|
||||
* Copyright (C) 2003 Red Hat <alan@redhat.com>
|
||||
* Copyright (C) 2007 MontaVista Software, Inc.
|
||||
*
|
||||
* May be copied or modified under the terms of the GNU General Public License
|
||||
*
|
||||
@ -205,41 +206,39 @@ static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted)
|
||||
unsigned long tfaddr = siimage_selreg(hwif, 0x02);
|
||||
|
||||
/* cheat for now and use the docs */
|
||||
switch(mode_wanted) {
|
||||
case 4:
|
||||
speedp = 0x10c1;
|
||||
speedt = 0x10c1;
|
||||
break;
|
||||
case 3:
|
||||
speedp = 0x10C3;
|
||||
speedt = 0x10C3;
|
||||
break;
|
||||
case 2:
|
||||
speedp = 0x1104;
|
||||
speedt = 0x1281;
|
||||
break;
|
||||
case 1:
|
||||
speedp = 0x2283;
|
||||
speedt = 0x1281;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
speedp = 0x328A;
|
||||
speedt = 0x328A;
|
||||
break;
|
||||
switch (mode_wanted) {
|
||||
case 4:
|
||||
speedp = 0x10c1;
|
||||
speedt = 0x10c1;
|
||||
break;
|
||||
case 3:
|
||||
speedp = 0x10c3;
|
||||
speedt = 0x10c3;
|
||||
break;
|
||||
case 2:
|
||||
speedp = 0x1104;
|
||||
speedt = 0x1281;
|
||||
break;
|
||||
case 1:
|
||||
speedp = 0x2283;
|
||||
speedt = 0x2283;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
speedp = 0x328a;
|
||||
speedt = 0x328a;
|
||||
break;
|
||||
}
|
||||
if (hwif->mmio)
|
||||
{
|
||||
hwif->OUTW(speedt, addr);
|
||||
hwif->OUTW(speedp, tfaddr);
|
||||
|
||||
if (hwif->mmio) {
|
||||
hwif->OUTW(speedp, addr);
|
||||
hwif->OUTW(speedt, tfaddr);
|
||||
/* Now set up IORDY */
|
||||
if(mode_wanted == 3 || mode_wanted == 4)
|
||||
hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
|
||||
else
|
||||
hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pci_write_config_word(hwif->pci_dev, addr, speedp);
|
||||
pci_write_config_word(hwif->pci_dev, tfaddr, speedt);
|
||||
pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp);
|
||||
@ -397,12 +396,9 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
if (!speed)
|
||||
return 0;
|
||||
|
||||
if (ide_set_xfer_rate(drive, speed))
|
||||
if (siimage_tune_chipset(drive, speed))
|
||||
return 0;
|
||||
|
||||
if (!drive->init_speed)
|
||||
drive->init_speed = speed;
|
||||
|
||||
return ide_dma_enable(drive);
|
||||
}
|
||||
|
||||
@ -418,25 +414,13 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
|
||||
static int siimage_config_drive_for_dma (ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct hd_driveid *id = drive->id;
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if ((id->capability & 1) != 0 && drive->autodma) {
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (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:
|
||||
if (ide_use_fast_pio(drive))
|
||||
config_chipset_for_pio(drive, 1);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* returns 1 if dma irq issued, 0 otherwise */
|
||||
@ -472,11 +456,11 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
|
||||
unsigned long addr = siimage_selreg(hwif, 0x1);
|
||||
|
||||
if (SATA_ERROR_REG) {
|
||||
u32 ext_stat = hwif->INL(base + 0x10);
|
||||
u32 ext_stat = readl((void __iomem *)(base + 0x10));
|
||||
u8 watchdog = 0;
|
||||
if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
|
||||
u32 sata_error = hwif->INL(SATA_ERROR_REG);
|
||||
hwif->OUTL(sata_error, SATA_ERROR_REG);
|
||||
u32 sata_error = readl((void __iomem *)SATA_ERROR_REG);
|
||||
writel(sata_error, (void __iomem *)SATA_ERROR_REG);
|
||||
watchdog = (sata_error & 0x00680000) ? 1 : 0;
|
||||
printk(KERN_WARNING "%s: sata_error = 0x%08x, "
|
||||
"watchdog = %d, %s\n",
|
||||
@ -493,11 +477,11 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
|
||||
}
|
||||
|
||||
/* return 1 if INTR asserted */
|
||||
if ((hwif->INB(hwif->dma_status) & 0x04) == 0x04)
|
||||
if ((readb((void __iomem *)hwif->dma_status) & 0x04) == 0x04)
|
||||
return 1;
|
||||
|
||||
/* return 1 if Device INTR asserted */
|
||||
if ((hwif->INB(addr) & 8) == 8)
|
||||
if ((readb((void __iomem *)addr) & 8) == 8)
|
||||
return 0; //return 1;
|
||||
|
||||
return 0;
|
||||
@ -519,9 +503,9 @@ static int siimage_busproc (ide_drive_t * drive, int state)
|
||||
u32 stat_config = 0;
|
||||
unsigned long addr = siimage_selreg(hwif, 0);
|
||||
|
||||
if (hwif->mmio) {
|
||||
stat_config = hwif->INL(addr);
|
||||
} else
|
||||
if (hwif->mmio)
|
||||
stat_config = readl((void __iomem *)addr);
|
||||
else
|
||||
pci_read_config_dword(hwif->pci_dev, addr, &stat_config);
|
||||
|
||||
switch (state) {
|
||||
@ -557,9 +541,10 @@ static int siimage_reset_poll (ide_drive_t *drive)
|
||||
if (SATA_STATUS_REG) {
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
|
||||
if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) {
|
||||
/* SATA_STATUS_REG is valid only when in MMIO mode */
|
||||
if ((readl((void __iomem *)SATA_STATUS_REG) & 0x03) != 0x03) {
|
||||
printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
|
||||
hwif->name, hwif->INL(SATA_STATUS_REG));
|
||||
hwif->name, readl((void __iomem *)SATA_STATUS_REG));
|
||||
HWGROUP(drive)->polling = 0;
|
||||
return ide_started;
|
||||
}
|
||||
@ -619,7 +604,8 @@ static void siimage_reset (ide_drive_t *drive)
|
||||
}
|
||||
|
||||
if (SATA_STATUS_REG) {
|
||||
u32 sata_stat = hwif->INL(SATA_STATUS_REG);
|
||||
/* SATA_STATUS_REG is valid only when in MMIO mode */
|
||||
u32 sata_stat = readl((void __iomem *)SATA_STATUS_REG);
|
||||
printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n",
|
||||
hwif->name, sata_stat, __FUNCTION__);
|
||||
if (!(sata_stat)) {
|
||||
@ -898,7 +884,8 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
|
||||
base = (unsigned long) addr;
|
||||
|
||||
hwif->dma_base = base + (ch ? 0x08 : 0x00);
|
||||
hwif->mmio = 2;
|
||||
|
||||
hwif->mmio = 1;
|
||||
}
|
||||
|
||||
static int is_dev_seagate_sata(ide_drive_t *drive)
|
||||
|
@ -667,68 +667,21 @@ static int config_chipset_for_dma (ide_drive_t *drive)
|
||||
return ide_dma_enable(drive);
|
||||
}
|
||||
|
||||
static int sis5513_config_drive_xfer_rate (ide_drive_t *drive)
|
||||
static int sis5513_config_xfer_rate(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct hd_driveid *id = drive->id;
|
||||
config_art_rwp_pio(drive, 5);
|
||||
|
||||
drive->init_speed = 0;
|
||||
|
||||
if (id && (id->capability & 1) && drive->autodma) {
|
||||
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_dma(drive)) {
|
||||
if (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:
|
||||
if (ide_use_fast_pio(drive))
|
||||
sis5513_tune_drive(drive, 5);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* initiates/aborts (U)DMA read/write operations on a drive. */
|
||||
static int sis5513_config_xfer_rate (ide_drive_t *drive)
|
||||
{
|
||||
config_drive_art_rwp(drive);
|
||||
config_art_rwp_pio(drive, 5);
|
||||
return sis5513_config_drive_xfer_rate(drive);
|
||||
}
|
||||
|
||||
/*
|
||||
Future simpler config_xfer_rate :
|
||||
When ide_find_best_mode is made bad-drive aware
|
||||
- remove config_drive_xfer_rate and config_chipset_for_dma,
|
||||
- replace config_xfer_rate with the following
|
||||
|
||||
static int sis5513_config_xfer_rate (ide_drive_t *drive)
|
||||
{
|
||||
u16 w80 = HWIF(drive)->udma_four;
|
||||
u16 speed;
|
||||
|
||||
config_drive_art_rwp(drive);
|
||||
config_art_rwp_pio(drive, 5);
|
||||
|
||||
speed = ide_find_best_mode(drive,
|
||||
XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
|
||||
(chipset_family >= ATA_33 ? XFER_UDMA : 0) |
|
||||
(w80 && chipset_family >= ATA_66 ? XFER_UDMA_66 : 0) |
|
||||
(w80 && chipset_family >= ATA_100a ? XFER_UDMA_100 : 0) |
|
||||
(w80 && chipset_family >= ATA_133a ? XFER_UDMA_133 : 0));
|
||||
|
||||
sis5513_tune_chipset(drive, speed);
|
||||
|
||||
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
|
||||
return HWIF(drive)->ide_dma_on(drive);
|
||||
return HWIF(drive)->ide_dma_off_quietly(drive);
|
||||
}
|
||||
*/
|
||||
|
||||
/* Chip detection and general config */
|
||||
static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name)
|
||||
{
|
||||
|
@ -161,14 +161,14 @@ static int sl82c105_check_drive (ide_drive_t *drive)
|
||||
if (id->field_valid & 2) {
|
||||
if ((id->dma_mword & hwif->mwdma_mask) ||
|
||||
(id->dma_1word & hwif->swdma_mask))
|
||||
return hwif->ide_dma_on(drive);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (__ide_dma_good_drive(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150)
|
||||
return 0;
|
||||
} while (0);
|
||||
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -215,7 +215,7 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive)
|
||||
* Was DMA enabled? If so, disable it - we're resetting the
|
||||
* host. The IDE layer will be handling the drive for us.
|
||||
*/
|
||||
val = hwif->INB(dma_base);
|
||||
val = inb(dma_base);
|
||||
if (val & 1) {
|
||||
outb(val & ~1, dma_base);
|
||||
printk("sl82c105: DMA was enabled\n");
|
||||
@ -259,28 +259,22 @@ static int sl82c105_ide_dma_on (ide_drive_t *drive)
|
||||
{
|
||||
DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name));
|
||||
|
||||
if (config_for_dma(drive)) {
|
||||
config_for_pio(drive, 4, 0, 0);
|
||||
return HWIF(drive)->ide_dma_off_quietly(drive);
|
||||
}
|
||||
if (config_for_dma(drive))
|
||||
return 1;
|
||||
printk(KERN_INFO "%s: DMA enabled\n", drive->name);
|
||||
return __ide_dma_on(drive);
|
||||
}
|
||||
|
||||
static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive)
|
||||
static void sl82c105_dma_off_quietly(ide_drive_t *drive)
|
||||
{
|
||||
u8 speed = XFER_PIO_0;
|
||||
int rc;
|
||||
|
||||
DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name));
|
||||
|
||||
rc = __ide_dma_off_quietly(drive);
|
||||
DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name));
|
||||
|
||||
ide_dma_off_quietly(drive);
|
||||
if (drive->pio_speed)
|
||||
speed = drive->pio_speed - XFER_PIO_0;
|
||||
config_for_pio(drive, speed, 0, 1);
|
||||
drive->current_speed = drive->pio_speed;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -401,11 +395,9 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
|
||||
/*
|
||||
* Initialise the chip
|
||||
*/
|
||||
|
||||
static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
|
||||
{
|
||||
unsigned int rev;
|
||||
u8 dma_state;
|
||||
|
||||
DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
|
||||
|
||||
@ -431,7 +423,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
|
||||
if (!hwif->dma_base)
|
||||
return;
|
||||
|
||||
dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60;
|
||||
rev = sl82c105_bridge_revision(hwif->pci_dev);
|
||||
if (rev <= 5) {
|
||||
/*
|
||||
@ -441,15 +432,12 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
|
||||
printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
|
||||
hwif->name, rev);
|
||||
} else {
|
||||
dma_state |= 0x60;
|
||||
|
||||
hwif->atapi_dma = 1;
|
||||
hwif->mwdma_mask = 0x07;
|
||||
hwif->swdma_mask = 0x07;
|
||||
hwif->mwdma_mask = 0x04;
|
||||
|
||||
hwif->ide_dma_check = &sl82c105_check_drive;
|
||||
hwif->ide_dma_on = &sl82c105_ide_dma_on;
|
||||
hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
|
||||
hwif->dma_off_quietly = &sl82c105_dma_off_quietly;
|
||||
hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
|
||||
hwif->dma_start = &sl82c105_ide_dma_start;
|
||||
hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
|
||||
@ -462,7 +450,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
|
||||
if (hwif->mate)
|
||||
hwif->serialized = hwif->mate->serialized = 1;
|
||||
}
|
||||
hwif->OUTB(dma_state, hwif->dma_base + 2);
|
||||
}
|
||||
|
||||
static ide_pci_device_t sl82c105_chipset __devinitdata = {
|
||||
|
@ -179,26 +179,16 @@ static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
|
||||
|
||||
static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
|
||||
{
|
||||
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) && slc90e66_config_drive_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
if (ide_use_fast_pio(drive))
|
||||
(void)slc90e66_tune_chipset(drive, XFER_PIO_0 +
|
||||
ide_get_best_pio_mode(drive, 255, 4, NULL));
|
||||
|
||||
goto fast_ata_pio;
|
||||
|
||||
} else if ((id->capability & 8) || (id->field_valid & 2)) {
|
||||
fast_ata_pio:
|
||||
(void) hwif->speedproc(drive, XFER_PIO_0 +
|
||||
ide_get_best_pio_mode(drive, 255, 4, NULL));
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
|
||||
|
@ -45,7 +45,7 @@ static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed)
|
||||
|
||||
scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
|
||||
scr |= mode;
|
||||
hwif->OUTW(scr, scr_port);
|
||||
outw(scr, scr_port);
|
||||
|
||||
return ide_config_drive_speed(drive, speed);
|
||||
}
|
||||
@ -89,15 +89,15 @@ static int tc86c001_timer_expiry(ide_drive_t *drive)
|
||||
"attempting recovery...\n", drive->name);
|
||||
|
||||
/* Stop DMA */
|
||||
hwif->OUTB(dma_cmd & ~0x01, hwif->dma_command);
|
||||
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 */
|
||||
outw(0, sc_base + 0x0a); /* Sector Count */
|
||||
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 */
|
||||
outb(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */
|
||||
outb(0x01, hwif->dma_command); /* set START_STOPBM */
|
||||
|
||||
/*
|
||||
* If an interrupt was pending, it should come thru shortly.
|
||||
@ -128,8 +128,8 @@ static void tc86c001_dma_start(ide_drive_t *drive)
|
||||
* 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 */
|
||||
outw(nsectors, sc_base + 0x0a); /* Sector Count */
|
||||
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);
|
||||
@ -168,7 +168,7 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
|
||||
}
|
||||
|
||||
/* System Control 1 Register bit 11 (ATA Hard Reset) write */
|
||||
hwif->OUTW(scr1, sc_base + 0x00);
|
||||
outw(scr1, sc_base + 0x00);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -185,23 +185,13 @@ static int config_chipset_for_dma(ide_drive_t *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 (ide_use_dma(drive) && config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
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:
|
||||
if (ide_use_fast_pio(drive))
|
||||
tc86c001_tune_drive(drive, 255);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
}
|
||||
/* IORDY not supported */
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
|
||||
@ -210,13 +200,13 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
|
||||
u16 scr1 = hwif->INW(sc_base + 0x00);;
|
||||
|
||||
/* System Control 1 Register bit 15 (Soft Reset) set */
|
||||
hwif->OUTW(scr1 | 0x8000, sc_base + 0x00);
|
||||
outw(scr1 | 0x8000, sc_base + 0x00);
|
||||
|
||||
/* System Control 1 Register bit 14 (FIFO Reset) set */
|
||||
hwif->OUTW(scr1 | 0x4000, sc_base + 0x00);
|
||||
outw(scr1 | 0x4000, sc_base + 0x00);
|
||||
|
||||
/* System Control 1 Register: reset clear */
|
||||
hwif->OUTW(scr1 & ~0xc000, sc_base + 0x00);
|
||||
outw(scr1 & ~0xc000, sc_base + 0x00);
|
||||
|
||||
/* Store the system control register base for convenience... */
|
||||
hwif->config_data = sc_base;
|
||||
@ -234,7 +224,7 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
|
||||
* 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);
|
||||
outw(0x0003, sc_base + 0x0c);
|
||||
|
||||
/* Sector Count Register limit */
|
||||
hwif->rqsize = 0xffff;
|
||||
|
@ -104,29 +104,21 @@ static int triflex_config_drive_for_dma(ide_drive_t *drive)
|
||||
{
|
||||
int speed = ide_dma_speed(drive, 0); /* No ultra speeds */
|
||||
|
||||
if (!speed) {
|
||||
u8 pspeed = ide_get_best_pio_mode(drive, 255, 4, NULL);
|
||||
speed = XFER_PIO_0 + pspeed;
|
||||
}
|
||||
|
||||
if (!speed)
|
||||
return 0;
|
||||
|
||||
(void) triflex_tune_chipset(drive, speed);
|
||||
return ide_dma_enable(drive);
|
||||
}
|
||||
|
||||
static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct hd_driveid *id = drive->id;
|
||||
if (ide_use_dma(drive) && triflex_config_drive_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if ((id->capability & 1) && drive->autodma) {
|
||||
if (ide_use_dma(drive)) {
|
||||
if (triflex_config_drive_for_dma(drive))
|
||||
return hwif->ide_dma_on(drive);
|
||||
}
|
||||
}
|
||||
triflex_tune_drive(drive, 255);
|
||||
|
||||
hwif->tuneproc(drive, 255);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
|
||||
|
@ -157,16 +157,16 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
|
||||
if (reg != hwif->select_data) {
|
||||
hwif->select_data = reg;
|
||||
/* set PIO/DMA */
|
||||
hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1);
|
||||
hwif->OUTW(reg & 0xff, hwif->config_data);
|
||||
outb(0x51 | (hwif->channel << 3), hwif->config_data + 1);
|
||||
outw(reg & 0xff, hwif->config_data);
|
||||
}
|
||||
|
||||
/* enable IRQ if not probing */
|
||||
if (drive->present) {
|
||||
reg = hwif->INW(hwif->config_data + 3);
|
||||
reg = inw(hwif->config_data + 3);
|
||||
reg &= 0x13;
|
||||
reg &= ~(1 << hwif->channel);
|
||||
hwif->OUTW(reg, hwif->config_data+3);
|
||||
outw(reg, hwif->config_data + 3);
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
@ -177,15 +177,12 @@ static void trm290_selectproc (ide_drive_t *drive)
|
||||
trm290_prepare_drive(drive, drive->using_dma);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDEDMA
|
||||
static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
|
||||
BUG_ON(HWGROUP(drive)->handler != NULL); /* paranoia check */
|
||||
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
|
||||
/* issue cmd to drive */
|
||||
hwif->OUTB(command, IDE_COMMAND_REG);
|
||||
outb(command, IDE_COMMAND_REG);
|
||||
}
|
||||
|
||||
static int trm290_ide_dma_setup(ide_drive_t *drive)
|
||||
@ -211,10 +208,10 @@ static int trm290_ide_dma_setup(ide_drive_t *drive)
|
||||
}
|
||||
/* select DMA xfer */
|
||||
trm290_prepare_drive(drive, 1);
|
||||
hwif->OUTL(hwif->dmatable_dma|rw, hwif->dma_command);
|
||||
outl(hwif->dmatable_dma | rw, hwif->dma_command);
|
||||
drive->waiting_for_dma = 1;
|
||||
/* start DMA */
|
||||
hwif->OUTW((count * 2) - 1, hwif->dma_status);
|
||||
outw((count * 2) - 1, hwif->dma_status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -230,7 +227,7 @@ static int trm290_ide_dma_end (ide_drive_t *drive)
|
||||
drive->waiting_for_dma = 0;
|
||||
/* purge DMA mappings */
|
||||
ide_destroy_dmatable(drive);
|
||||
status = hwif->INW(hwif->dma_status);
|
||||
status = inw(hwif->dma_status);
|
||||
return (status != 0x00ff);
|
||||
}
|
||||
|
||||
@ -239,10 +236,9 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive)
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
u16 status = 0;
|
||||
|
||||
status = hwif->INW(hwif->dma_status);
|
||||
status = inw(hwif->dma_status);
|
||||
return (status == 0x00ff);
|
||||
}
|
||||
#endif /* CONFIG_BLK_DEV_IDEDMA */
|
||||
|
||||
/*
|
||||
* Invoked from ide-dma.c at boot time.
|
||||
@ -269,15 +265,15 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
|
||||
|
||||
local_irq_save(flags);
|
||||
/* put config reg into first byte of hwif->select_data */
|
||||
hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1);
|
||||
outb(0x51 | (hwif->channel << 3), hwif->config_data + 1);
|
||||
/* select PIO as default */
|
||||
hwif->select_data = 0x21;
|
||||
hwif->OUTB(hwif->select_data, hwif->config_data);
|
||||
outb(hwif->select_data, hwif->config_data);
|
||||
/* get IRQ info */
|
||||
reg = hwif->INB(hwif->config_data+3);
|
||||
reg = inb(hwif->config_data + 3);
|
||||
/* mask IRQs for both ports */
|
||||
reg = (reg & 0x10) | 0x03;
|
||||
hwif->OUTB(reg, hwif->config_data+3);
|
||||
outb(reg, hwif->config_data + 3);
|
||||
local_irq_restore(flags);
|
||||
|
||||
if ((reg & 0x10))
|
||||
@ -289,13 +285,11 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
|
||||
|
||||
ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDEDMA
|
||||
hwif->dma_setup = &trm290_ide_dma_setup;
|
||||
hwif->dma_exec_cmd = &trm290_ide_dma_exec_cmd;
|
||||
hwif->dma_start = &trm290_ide_dma_start;
|
||||
hwif->ide_dma_end = &trm290_ide_dma_end;
|
||||
hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq;
|
||||
#endif /* CONFIG_BLK_DEV_IDEDMA */
|
||||
|
||||
hwif->selectproc = &trm290_selectproc;
|
||||
hwif->autodma = 0; /* play it safe for now */
|
||||
@ -312,16 +306,16 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
|
||||
static u16 next_offset = 0;
|
||||
u8 old_mask;
|
||||
|
||||
hwif->OUTB(0x54|(hwif->channel<<3), hwif->config_data+1);
|
||||
old = hwif->INW(hwif->config_data);
|
||||
outb(0x54 | (hwif->channel << 3), hwif->config_data + 1);
|
||||
old = inw(hwif->config_data);
|
||||
old &= ~1;
|
||||
old_mask = hwif->INB(old+2);
|
||||
old_mask = inb(old + 2);
|
||||
if (old != compat && old_mask == 0xff) {
|
||||
/* leave lower 10 bits untouched */
|
||||
compat += (next_offset += 0x400);
|
||||
hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2;
|
||||
hwif->OUTW(compat|1, hwif->config_data);
|
||||
new = hwif->INW(hwif->config_data);
|
||||
outw(compat | 1, hwif->config_data);
|
||||
new = inw(hwif->config_data);
|
||||
printk(KERN_INFO "%s: control basereg workaround: "
|
||||
"old=0x%04x, new=0x%04x\n",
|
||||
hwif->name, old, new & ~1);
|
||||
|
@ -240,8 +240,9 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
|
||||
via_set_drive(drive, speed);
|
||||
|
||||
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
|
||||
return hwif->ide_dma_on(drive);
|
||||
return hwif->ide_dma_off_quietly(drive);
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
|
||||
|
@ -1237,7 +1237,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
|
||||
hwif->OUTBSYNC = pmac_outbsync;
|
||||
|
||||
/* Tell common code _not_ to mess with resources */
|
||||
hwif->mmio = 2;
|
||||
hwif->mmio = 1;
|
||||
hwif->hwif_data = pmif;
|
||||
pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq);
|
||||
memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
|
||||
@ -1979,16 +1979,12 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
pmac_ide_dma_host_off (ide_drive_t *drive)
|
||||
static void pmac_ide_dma_host_off(ide_drive_t *drive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pmac_ide_dma_host_on (ide_drive_t *drive)
|
||||
static int pmac_ide_dma_host_on(ide_drive_t *drive)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2034,7 +2030,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
|
||||
return;
|
||||
}
|
||||
|
||||
hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
|
||||
hwif->dma_off_quietly = &ide_dma_off_quietly;
|
||||
hwif->ide_dma_on = &__ide_dma_on;
|
||||
hwif->ide_dma_check = &pmac_ide_dma_check;
|
||||
hwif->dma_setup = &pmac_ide_dma_setup;
|
||||
@ -2042,8 +2038,8 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
|
||||
hwif->dma_start = &pmac_ide_dma_start;
|
||||
hwif->ide_dma_end = &pmac_ide_dma_end;
|
||||
hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
|
||||
hwif->ide_dma_host_off = &pmac_ide_dma_host_off;
|
||||
hwif->ide_dma_host_on = &pmac_ide_dma_host_on;
|
||||
hwif->dma_host_off = &pmac_ide_dma_host_off;
|
||||
hwif->dma_host_on = &pmac_ide_dma_host_on;
|
||||
hwif->ide_dma_timeout = &__ide_dma_timeout;
|
||||
hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
|
||||
|
||||
|
831
drivers/ide/ppc/scc_pata.c
Normal file
831
drivers/ide/ppc/scc_pata.c
Normal file
@ -0,0 +1,831 @@
|
||||
/*
|
||||
* Support for IDE interfaces on Celleb platform
|
||||
*
|
||||
* (C) Copyright 2006 TOSHIBA CORPORATION
|
||||
*
|
||||
* This code is based on drivers/ide/pci/siimage.c:
|
||||
* Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
|
||||
* Copyright (C) 2003 Red Hat <alan@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#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>
|
||||
|
||||
#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4
|
||||
|
||||
#define SCC_PATA_NAME "scc IDE"
|
||||
|
||||
#define TDVHSEL_MASTER 0x00000001
|
||||
#define TDVHSEL_SLAVE 0x00000004
|
||||
|
||||
#define MODE_JCUSFEN 0x00000080
|
||||
|
||||
#define CCKCTRL_ATARESET 0x00040000
|
||||
#define CCKCTRL_BUFCNT 0x00020000
|
||||
#define CCKCTRL_CRST 0x00010000
|
||||
#define CCKCTRL_OCLKEN 0x00000100
|
||||
#define CCKCTRL_ATACLKOEN 0x00000002
|
||||
#define CCKCTRL_LCLKEN 0x00000001
|
||||
|
||||
#define QCHCD_IOS_SS 0x00000001
|
||||
|
||||
#define QCHSD_STPDIAG 0x00020000
|
||||
|
||||
#define INTMASK_MSK 0xD1000012
|
||||
#define INTSTS_SERROR 0x80000000
|
||||
#define INTSTS_PRERR 0x40000000
|
||||
#define INTSTS_RERR 0x10000000
|
||||
#define INTSTS_ICERR 0x01000000
|
||||
#define INTSTS_BMSINT 0x00000010
|
||||
#define INTSTS_BMHE 0x00000008
|
||||
#define INTSTS_IOIRQS 0x00000004
|
||||
#define INTSTS_INTRQ 0x00000002
|
||||
#define INTSTS_ACTEINT 0x00000001
|
||||
|
||||
#define ECMODE_VALUE 0x01
|
||||
|
||||
static struct scc_ports {
|
||||
unsigned long ctl, dma;
|
||||
unsigned char hwif_id; /* for removing hwif from system */
|
||||
} scc_ports[MAX_HWIFS];
|
||||
|
||||
/* PIO transfer mode table */
|
||||
/* JCHST */
|
||||
static unsigned long JCHSTtbl[2][7] = {
|
||||
{0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */
|
||||
{0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */
|
||||
};
|
||||
|
||||
/* JCHHT */
|
||||
static unsigned long JCHHTtbl[2][7] = {
|
||||
{0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */
|
||||
{0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */
|
||||
};
|
||||
|
||||
/* JCHCT */
|
||||
static unsigned long JCHCTtbl[2][7] = {
|
||||
{0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */
|
||||
{0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */
|
||||
};
|
||||
|
||||
|
||||
/* DMA transfer mode table */
|
||||
/* JCHDCTM/JCHDCTS */
|
||||
static unsigned long JCHDCTxtbl[2][7] = {
|
||||
{0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */
|
||||
{0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */
|
||||
};
|
||||
|
||||
/* JCSTWTM/JCSTWTS */
|
||||
static unsigned long JCSTWTxtbl[2][7] = {
|
||||
{0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */
|
||||
{0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */
|
||||
};
|
||||
|
||||
/* JCTSS */
|
||||
static unsigned long JCTSStbl[2][7] = {
|
||||
{0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */
|
||||
{0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */
|
||||
};
|
||||
|
||||
/* JCENVT */
|
||||
static unsigned long JCENVTtbl[2][7] = {
|
||||
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */
|
||||
{0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */
|
||||
};
|
||||
|
||||
/* JCACTSELS/JCACTSELM */
|
||||
static unsigned long JCACTSELtbl[2][7] = {
|
||||
{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */
|
||||
};
|
||||
|
||||
|
||||
static u8 scc_ide_inb(unsigned long port)
|
||||
{
|
||||
u32 data = in_be32((void*)port);
|
||||
return (u8)data;
|
||||
}
|
||||
|
||||
static u16 scc_ide_inw(unsigned long port)
|
||||
{
|
||||
u32 data = in_be32((void*)port);
|
||||
return (u16)data;
|
||||
}
|
||||
|
||||
static void scc_ide_insw(unsigned long port, void *addr, u32 count)
|
||||
{
|
||||
u16 *ptr = (u16 *)addr;
|
||||
while (count--) {
|
||||
*ptr++ = le16_to_cpu(in_be32((void*)port));
|
||||
}
|
||||
}
|
||||
|
||||
static void scc_ide_insl(unsigned long port, void *addr, u32 count)
|
||||
{
|
||||
u16 *ptr = (u16 *)addr;
|
||||
while (count--) {
|
||||
*ptr++ = le16_to_cpu(in_be32((void*)port));
|
||||
*ptr++ = le16_to_cpu(in_be32((void*)port));
|
||||
}
|
||||
}
|
||||
|
||||
static void scc_ide_outb(u8 addr, unsigned long port)
|
||||
{
|
||||
out_be32((void*)port, addr);
|
||||
}
|
||||
|
||||
static void scc_ide_outw(u16 addr, unsigned long port)
|
||||
{
|
||||
out_be32((void*)port, addr);
|
||||
}
|
||||
|
||||
static void
|
||||
scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
|
||||
out_be32((void*)port, addr);
|
||||
__asm__ __volatile__("eieio":::"memory");
|
||||
in_be32((void*)(hwif->dma_base + 0x01c));
|
||||
__asm__ __volatile__("eieio":::"memory");
|
||||
}
|
||||
|
||||
static void
|
||||
scc_ide_outsw(unsigned long port, void *addr, u32 count)
|
||||
{
|
||||
u16 *ptr = (u16 *)addr;
|
||||
while (count--) {
|
||||
out_be32((void*)port, cpu_to_le16(*ptr++));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scc_ide_outsl(unsigned long port, void *addr, u32 count)
|
||||
{
|
||||
u16 *ptr = (u16 *)addr;
|
||||
while (count--) {
|
||||
out_be32((void*)port, cpu_to_le16(*ptr++));
|
||||
out_be32((void*)port, cpu_to_le16(*ptr++));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* scc_ratemask - Compute available modes
|
||||
* @drive: IDE drive
|
||||
*
|
||||
* Compute the available speeds for the devices on the interface.
|
||||
* Enforce UDMA33 as a limit if there is no 80pin cable present.
|
||||
*/
|
||||
|
||||
static u8 scc_ratemask(ide_drive_t *drive)
|
||||
{
|
||||
u8 mode = 4;
|
||||
|
||||
if (!eighty_ninty_three(drive))
|
||||
mode = min(mode, (u8)1);
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* scc_tuneproc - tune a drive PIO mode
|
||||
* @drive: drive to tune
|
||||
* @mode_wanted: the target operating mode
|
||||
*
|
||||
* Load the timing settings for this device mode into the
|
||||
* controller.
|
||||
*/
|
||||
|
||||
static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
struct scc_ports *ports = ide_get_hwifdata(hwif);
|
||||
unsigned long ctl_base = ports->ctl;
|
||||
unsigned long cckctrl_port = ctl_base + 0xff0;
|
||||
unsigned long piosht_port = ctl_base + 0x000;
|
||||
unsigned long pioct_port = ctl_base + 0x004;
|
||||
unsigned long reg;
|
||||
unsigned char speed = XFER_PIO_0;
|
||||
int offset;
|
||||
|
||||
mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4, NULL);
|
||||
switch (mode_wanted) {
|
||||
case 4:
|
||||
speed = XFER_PIO_4;
|
||||
break;
|
||||
case 3:
|
||||
speed = XFER_PIO_3;
|
||||
break;
|
||||
case 2:
|
||||
speed = XFER_PIO_2;
|
||||
break;
|
||||
case 1:
|
||||
speed = XFER_PIO_1;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
speed = XFER_PIO_0;
|
||||
break;
|
||||
}
|
||||
|
||||
reg = in_be32((void __iomem *)cckctrl_port);
|
||||
if (reg & CCKCTRL_ATACLKOEN) {
|
||||
offset = 1; /* 133MHz */
|
||||
} else {
|
||||
offset = 0; /* 100MHz */
|
||||
}
|
||||
reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted];
|
||||
out_be32((void __iomem *)piosht_port, reg);
|
||||
reg = JCHCTtbl[offset][mode_wanted];
|
||||
out_be32((void __iomem *)pioct_port, reg);
|
||||
|
||||
ide_config_drive_speed(drive, speed);
|
||||
}
|
||||
|
||||
/**
|
||||
* scc_tune_chipset - tune a drive DMA mode
|
||||
* @drive: Drive to set up
|
||||
* @xferspeed: speed we want to achieve
|
||||
*
|
||||
* Load the timing settings for this device mode into the
|
||||
* controller.
|
||||
*/
|
||||
|
||||
static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
u8 speed = ide_rate_filter(scc_ratemask(drive), xferspeed);
|
||||
struct scc_ports *ports = ide_get_hwifdata(hwif);
|
||||
unsigned long ctl_base = ports->ctl;
|
||||
unsigned long cckctrl_port = ctl_base + 0xff0;
|
||||
unsigned long mdmact_port = ctl_base + 0x008;
|
||||
unsigned long mcrcst_port = ctl_base + 0x00c;
|
||||
unsigned long sdmact_port = ctl_base + 0x010;
|
||||
unsigned long scrcst_port = ctl_base + 0x014;
|
||||
unsigned long udenvt_port = ctl_base + 0x018;
|
||||
unsigned long tdvhsel_port = ctl_base + 0x020;
|
||||
int is_slave = (&hwif->drives[1] == drive);
|
||||
int offset, idx;
|
||||
unsigned long reg;
|
||||
unsigned long jcactsel;
|
||||
|
||||
reg = in_be32((void __iomem *)cckctrl_port);
|
||||
if (reg & CCKCTRL_ATACLKOEN) {
|
||||
offset = 1; /* 133MHz */
|
||||
} else {
|
||||
offset = 0; /* 100MHz */
|
||||
}
|
||||
|
||||
switch (speed) {
|
||||
case XFER_UDMA_6:
|
||||
idx = 6;
|
||||
break;
|
||||
case XFER_UDMA_5:
|
||||
idx = 5;
|
||||
break;
|
||||
case XFER_UDMA_4:
|
||||
idx = 4;
|
||||
break;
|
||||
case XFER_UDMA_3:
|
||||
idx = 3;
|
||||
break;
|
||||
case XFER_UDMA_2:
|
||||
idx = 2;
|
||||
break;
|
||||
case XFER_UDMA_1:
|
||||
idx = 1;
|
||||
break;
|
||||
case XFER_UDMA_0:
|
||||
idx = 0;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
jcactsel = JCACTSELtbl[offset][idx];
|
||||
if (is_slave) {
|
||||
out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]);
|
||||
out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]);
|
||||
jcactsel = jcactsel << 2;
|
||||
out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel);
|
||||
} else {
|
||||
out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]);
|
||||
out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]);
|
||||
out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel);
|
||||
}
|
||||
reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx];
|
||||
out_be32((void __iomem *)udenvt_port, reg);
|
||||
|
||||
return ide_config_drive_speed(drive, speed);
|
||||
}
|
||||
|
||||
/**
|
||||
* scc_config_chipset_for_dma - configure for DMA
|
||||
* @drive: drive to configure
|
||||
*
|
||||
* Called by scc_config_drive_for_dma().
|
||||
*/
|
||||
|
||||
static int scc_config_chipset_for_dma(ide_drive_t *drive)
|
||||
{
|
||||
u8 speed = ide_dma_speed(drive, scc_ratemask(drive));
|
||||
|
||||
if (!speed)
|
||||
return 0;
|
||||
|
||||
if (scc_tune_chipset(drive, speed))
|
||||
return 0;
|
||||
|
||||
return ide_dma_enable(drive);
|
||||
}
|
||||
|
||||
/**
|
||||
* scc_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.
|
||||
* (return 1)
|
||||
*/
|
||||
|
||||
static int scc_config_drive_for_dma(ide_drive_t *drive)
|
||||
{
|
||||
if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive))
|
||||
return 0;
|
||||
|
||||
if (ide_use_fast_pio(drive))
|
||||
scc_tuneproc(drive, 4);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* scc_ide_dma_setup - begin a DMA phase
|
||||
* @drive: target device
|
||||
*
|
||||
* Build an IDE DMA PRD (IDE speak for scatter gather table)
|
||||
* and then set up the DMA transfer registers.
|
||||
*
|
||||
* Returns 0 on success. If a PIO fallback is required then 1
|
||||
* is returned.
|
||||
*/
|
||||
|
||||
static int scc_dma_setup(ide_drive_t *drive)
|
||||
{
|
||||
ide_hwif_t *hwif = drive->hwif;
|
||||
struct request *rq = HWGROUP(drive)->rq;
|
||||
unsigned int reading;
|
||||
u8 dma_stat;
|
||||
|
||||
if (rq_data_dir(rq))
|
||||
reading = 0;
|
||||
else
|
||||
reading = 1 << 3;
|
||||
|
||||
/* fall back to pio! */
|
||||
if (!ide_build_dmatable(drive, rq)) {
|
||||
ide_map_sg(drive, rq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* PRD table */
|
||||
out_be32((void __iomem *)hwif->dma_prdtable, hwif->dmatable_dma);
|
||||
|
||||
/* specify r/w */
|
||||
out_be32((void __iomem *)hwif->dma_command, reading);
|
||||
|
||||
/* read dma_status for INTR & ERROR flags */
|
||||
dma_stat = in_be32((void __iomem *)hwif->dma_status);
|
||||
|
||||
/* clear INTR & ERROR flags */
|
||||
out_be32((void __iomem *)hwif->dma_status, dma_stat|6);
|
||||
drive->waiting_for_dma = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* scc_ide_dma_end - Stop DMA
|
||||
* @drive: IDE drive
|
||||
*
|
||||
* Check and clear INT Status register.
|
||||
* Then call __ide_dma_end().
|
||||
*/
|
||||
|
||||
static int scc_ide_dma_end(ide_drive_t * drive)
|
||||
{
|
||||
ide_hwif_t *hwif = HWIF(drive);
|
||||
unsigned long intsts_port = hwif->dma_base + 0x014;
|
||||
u32 reg;
|
||||
|
||||
while (1) {
|
||||
reg = in_be32((void __iomem *)intsts_port);
|
||||
|
||||
if (reg & INTSTS_SERROR) {
|
||||
printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME);
|
||||
out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT);
|
||||
|
||||
out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reg & INTSTS_PRERR) {
|
||||
u32 maea0, maec0;
|
||||
unsigned long ctl_base = hwif->config_data;
|
||||
|
||||
maea0 = in_be32((void __iomem *)(ctl_base + 0xF50));
|
||||
maec0 = in_be32((void __iomem *)(ctl_base + 0xF54));
|
||||
|
||||
printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0);
|
||||
|
||||
out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT);
|
||||
|
||||
out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reg & INTSTS_RERR) {
|
||||
printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME);
|
||||
out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT);
|
||||
|
||||
out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reg & INTSTS_ICERR) {
|
||||
out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
|
||||
|
||||
printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME);
|
||||
out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reg & INTSTS_BMSINT) {
|
||||
printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME);
|
||||
out_be32((void __iomem *)intsts_port, INTSTS_BMSINT);
|
||||
|
||||
ide_do_reset(drive);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reg & INTSTS_BMHE) {
|
||||
out_be32((void __iomem *)intsts_port, INTSTS_BMHE);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reg & INTSTS_ACTEINT) {
|
||||
out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reg & INTSTS_IOIRQS) {
|
||||
out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return __ide_dma_end(drive);
|
||||
}
|
||||
|
||||
/**
|
||||
* setup_mmio_scc - map CTRL/BMID region
|
||||
* @dev: PCI device we are configuring
|
||||
* @name: device name
|
||||
*
|
||||
*/
|
||||
|
||||
static int setup_mmio_scc (struct pci_dev *dev, const char *name)
|
||||
{
|
||||
unsigned long ctl_base = pci_resource_start(dev, 0);
|
||||
unsigned long dma_base = pci_resource_start(dev, 1);
|
||||
unsigned long ctl_size = pci_resource_len(dev, 0);
|
||||
unsigned long dma_size = pci_resource_len(dev, 1);
|
||||
void *ctl_addr;
|
||||
void *dma_addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_HWIFS; i++) {
|
||||
if (scc_ports[i].ctl == 0)
|
||||
break;
|
||||
}
|
||||
if (i >= MAX_HWIFS)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!request_mem_region(ctl_base, ctl_size, name)) {
|
||||
printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME);
|
||||
goto fail_0;
|
||||
}
|
||||
|
||||
if (!request_mem_region(dma_base, dma_size, name)) {
|
||||
printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME);
|
||||
goto fail_1;
|
||||
}
|
||||
|
||||
if ((ctl_addr = ioremap(ctl_base, ctl_size)) == NULL)
|
||||
goto fail_2;
|
||||
|
||||
if ((dma_addr = ioremap(dma_base, dma_size)) == NULL)
|
||||
goto fail_3;
|
||||
|
||||
pci_set_master(dev);
|
||||
scc_ports[i].ctl = (unsigned long)ctl_addr;
|
||||
scc_ports[i].dma = (unsigned long)dma_addr;
|
||||
pci_set_drvdata(dev, (void *) &scc_ports[i]);
|
||||
|
||||
return 1;
|
||||
|
||||
fail_3:
|
||||
iounmap(ctl_addr);
|
||||
fail_2:
|
||||
release_mem_region(dma_base, dma_size);
|
||||
fail_1:
|
||||
release_mem_region(ctl_base, ctl_size);
|
||||
fail_0:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* init_setup_scc - set up an SCC PATA Controller
|
||||
* @dev: PCI device
|
||||
* @d: IDE PCI device
|
||||
*
|
||||
* Perform the initial set up for this device.
|
||||
*/
|
||||
|
||||
static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d)
|
||||
{
|
||||
unsigned long ctl_base;
|
||||
unsigned long dma_base;
|
||||
unsigned long cckctrl_port;
|
||||
unsigned long intmask_port;
|
||||
unsigned long mode_port;
|
||||
unsigned long ecmode_port;
|
||||
unsigned long dma_status_port;
|
||||
u32 reg = 0;
|
||||
struct scc_ports *ports;
|
||||
int rc;
|
||||
|
||||
rc = setup_mmio_scc(dev, d->name);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
ports = pci_get_drvdata(dev);
|
||||
ctl_base = ports->ctl;
|
||||
dma_base = ports->dma;
|
||||
cckctrl_port = ctl_base + 0xff0;
|
||||
intmask_port = dma_base + 0x010;
|
||||
mode_port = ctl_base + 0x024;
|
||||
ecmode_port = ctl_base + 0xf00;
|
||||
dma_status_port = dma_base + 0x004;
|
||||
|
||||
/* controller initialization */
|
||||
reg = 0;
|
||||
out_be32((void*)cckctrl_port, reg);
|
||||
reg |= CCKCTRL_ATACLKOEN;
|
||||
out_be32((void*)cckctrl_port, reg);
|
||||
reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN;
|
||||
out_be32((void*)cckctrl_port, reg);
|
||||
reg |= CCKCTRL_CRST;
|
||||
out_be32((void*)cckctrl_port, reg);
|
||||
|
||||
for (;;) {
|
||||
reg = in_be32((void*)cckctrl_port);
|
||||
if (reg & CCKCTRL_CRST)
|
||||
break;
|
||||
udelay(5000);
|
||||
}
|
||||
|
||||
reg |= CCKCTRL_ATARESET;
|
||||
out_be32((void*)cckctrl_port, reg);
|
||||
|
||||
out_be32((void*)ecmode_port, ECMODE_VALUE);
|
||||
out_be32((void*)mode_port, MODE_JCUSFEN);
|
||||
out_be32((void*)intmask_port, INTMASK_MSK);
|
||||
|
||||
return ide_setup_pci_device(dev, d);
|
||||
}
|
||||
|
||||
/**
|
||||
* init_mmio_iops_scc - set up the iops for MMIO
|
||||
* @hwif: interface to set up
|
||||
*
|
||||
*/
|
||||
|
||||
static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
|
||||
{
|
||||
struct pci_dev *dev = hwif->pci_dev;
|
||||
struct scc_ports *ports = pci_get_drvdata(dev);
|
||||
unsigned long dma_base = ports->dma;
|
||||
|
||||
ide_set_hwifdata(hwif, ports);
|
||||
|
||||
hwif->INB = scc_ide_inb;
|
||||
hwif->INW = scc_ide_inw;
|
||||
hwif->INSW = scc_ide_insw;
|
||||
hwif->INSL = scc_ide_insl;
|
||||
hwif->OUTB = scc_ide_outb;
|
||||
hwif->OUTBSYNC = scc_ide_outbsync;
|
||||
hwif->OUTW = scc_ide_outw;
|
||||
hwif->OUTSW = scc_ide_outsw;
|
||||
hwif->OUTSL = scc_ide_outsl;
|
||||
|
||||
hwif->io_ports[IDE_DATA_OFFSET] = dma_base + 0x20;
|
||||
hwif->io_ports[IDE_ERROR_OFFSET] = dma_base + 0x24;
|
||||
hwif->io_ports[IDE_NSECTOR_OFFSET] = dma_base + 0x28;
|
||||
hwif->io_ports[IDE_SECTOR_OFFSET] = dma_base + 0x2c;
|
||||
hwif->io_ports[IDE_LCYL_OFFSET] = dma_base + 0x30;
|
||||
hwif->io_ports[IDE_HCYL_OFFSET] = dma_base + 0x34;
|
||||
hwif->io_ports[IDE_SELECT_OFFSET] = dma_base + 0x38;
|
||||
hwif->io_ports[IDE_STATUS_OFFSET] = dma_base + 0x3c;
|
||||
hwif->io_ports[IDE_CONTROL_OFFSET] = dma_base + 0x40;
|
||||
|
||||
hwif->irq = hwif->pci_dev->irq;
|
||||
hwif->dma_base = dma_base;
|
||||
hwif->config_data = ports->ctl;
|
||||
hwif->mmio = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* init_iops_scc - set up iops
|
||||
* @hwif: interface to set up
|
||||
*
|
||||
* Do the basic setup for the SCC hardware interface
|
||||
* and then do the MMIO setup.
|
||||
*/
|
||||
|
||||
static void __devinit init_iops_scc(ide_hwif_t *hwif)
|
||||
{
|
||||
struct pci_dev *dev = hwif->pci_dev;
|
||||
hwif->hwif_data = NULL;
|
||||
if (pci_get_drvdata(dev) == NULL)
|
||||
return;
|
||||
init_mmio_iops_scc(hwif);
|
||||
}
|
||||
|
||||
/**
|
||||
* init_hwif_scc - set up hwif
|
||||
* @hwif: interface to set up
|
||||
*
|
||||
* We do the basic set up of the interface structure. The SCC
|
||||
* requires several custom handlers so we override the default
|
||||
* ide DMA handlers appropriately.
|
||||
*/
|
||||
|
||||
static void __devinit init_hwif_scc(ide_hwif_t *hwif)
|
||||
{
|
||||
struct scc_ports *ports = ide_get_hwifdata(hwif);
|
||||
|
||||
ports->hwif_id = hwif->index;
|
||||
|
||||
hwif->dma_command = hwif->dma_base;
|
||||
hwif->dma_status = hwif->dma_base + 0x04;
|
||||
hwif->dma_prdtable = hwif->dma_base + 0x08;
|
||||
|
||||
/* PTERADD */
|
||||
out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
|
||||
|
||||
hwif->dma_setup = scc_dma_setup;
|
||||
hwif->ide_dma_end = scc_ide_dma_end;
|
||||
hwif->speedproc = scc_tune_chipset;
|
||||
hwif->tuneproc = scc_tuneproc;
|
||||
hwif->ide_dma_check = scc_config_drive_for_dma;
|
||||
|
||||
hwif->drives[0].autotune = IDE_TUNE_AUTO;
|
||||
hwif->drives[1].autotune = IDE_TUNE_AUTO;
|
||||
|
||||
if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) {
|
||||
hwif->ultra_mask = 0x7f; /* 133MHz */
|
||||
} else {
|
||||
hwif->ultra_mask = 0x3f; /* 100MHz */
|
||||
}
|
||||
hwif->mwdma_mask = 0x00;
|
||||
hwif->swdma_mask = 0x00;
|
||||
hwif->atapi_dma = 1;
|
||||
|
||||
/* we support 80c cable only. */
|
||||
hwif->udma_four = 1;
|
||||
|
||||
hwif->autodma = 0;
|
||||
if (!noautodma)
|
||||
hwif->autodma = 1;
|
||||
hwif->drives[0].autodma = hwif->autodma;
|
||||
hwif->drives[1].autodma = hwif->autodma;
|
||||
}
|
||||
|
||||
#define DECLARE_SCC_DEV(name_str) \
|
||||
{ \
|
||||
.name = name_str, \
|
||||
.init_setup = init_setup_scc, \
|
||||
.init_iops = init_iops_scc, \
|
||||
.init_hwif = init_hwif_scc, \
|
||||
.channels = 1, \
|
||||
.autodma = AUTODMA, \
|
||||
.bootable = ON_BOARD, \
|
||||
}
|
||||
|
||||
static ide_pci_device_t scc_chipsets[] __devinitdata = {
|
||||
/* 0 */ DECLARE_SCC_DEV("sccIDE"),
|
||||
};
|
||||
|
||||
/**
|
||||
* scc_init_one - pci layer discovery entry
|
||||
* @dev: PCI device
|
||||
* @id: ident table entry
|
||||
*
|
||||
* Called by the PCI code when it finds an SCC PATA controller.
|
||||
* We then use the IDE PCI generic helper to do most of the work.
|
||||
*/
|
||||
|
||||
static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
{
|
||||
ide_pci_device_t *d = &scc_chipsets[id->driver_data];
|
||||
return d->init_setup(dev, d);
|
||||
}
|
||||
|
||||
/**
|
||||
* scc_remove - pci layer remove entry
|
||||
* @dev: PCI device
|
||||
*
|
||||
* Called by the PCI code when it removes an SCC PATA controller.
|
||||
*/
|
||||
|
||||
static void __devexit scc_remove(struct pci_dev *dev)
|
||||
{
|
||||
struct scc_ports *ports = pci_get_drvdata(dev);
|
||||
ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id];
|
||||
unsigned long ctl_base = pci_resource_start(dev, 0);
|
||||
unsigned long dma_base = pci_resource_start(dev, 1);
|
||||
unsigned long ctl_size = pci_resource_len(dev, 0);
|
||||
unsigned long dma_size = pci_resource_len(dev, 1);
|
||||
|
||||
if (hwif->dmatable_cpu) {
|
||||
pci_free_consistent(hwif->pci_dev,
|
||||
PRD_ENTRIES * PRD_BYTES,
|
||||
hwif->dmatable_cpu,
|
||||
hwif->dmatable_dma);
|
||||
hwif->dmatable_cpu = NULL;
|
||||
}
|
||||
|
||||
ide_unregister(hwif->index);
|
||||
|
||||
hwif->chipset = ide_unknown;
|
||||
iounmap((void*)ports->dma);
|
||||
iounmap((void*)ports->ctl);
|
||||
release_mem_region(dma_base, dma_size);
|
||||
release_mem_region(ctl_base, ctl_size);
|
||||
memset(ports, 0, sizeof(*ports));
|
||||
}
|
||||
|
||||
static struct pci_device_id scc_pci_tbl[] = {
|
||||
{ PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{ 0, },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "SCC IDE",
|
||||
.id_table = scc_pci_tbl,
|
||||
.probe = scc_init_one,
|
||||
.remove = scc_remove,
|
||||
};
|
||||
|
||||
static int scc_ide_init(void)
|
||||
{
|
||||
return ide_pci_register_driver(&driver);
|
||||
}
|
||||
|
||||
module_init(scc_ide_init);
|
||||
/* -- No exit code?
|
||||
static void scc_ide_exit(void)
|
||||
{
|
||||
ide_pci_unregister_driver(&driver);
|
||||
}
|
||||
module_exit(scc_ide_exit);
|
||||
*/
|
||||
|
||||
|
||||
MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE");
|
||||
MODULE_LICENSE("GPL");
|
@ -801,15 +801,10 @@ static int idescsi_ide_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct gendisk *disk = inode->i_bdev->bd_disk;
|
||||
struct ide_scsi_obj *scsi;
|
||||
ide_drive_t *drive;
|
||||
|
||||
if (!(scsi = ide_scsi_get(disk)))
|
||||
return -ENXIO;
|
||||
|
||||
drive = scsi->drive;
|
||||
|
||||
drive->usage++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -817,9 +812,6 @@ static int idescsi_ide_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct gendisk *disk = inode->i_bdev->bd_disk;
|
||||
struct ide_scsi_obj *scsi = ide_scsi_g(disk);
|
||||
ide_drive_t *drive = scsi->drive;
|
||||
|
||||
drive->usage--;
|
||||
|
||||
ide_scsi_put(scsi);
|
||||
|
||||
|
@ -636,7 +636,6 @@ typedef struct ide_drive_s {
|
||||
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
|
||||
unsigned int cyl; /* "real" number of cyls */
|
||||
unsigned int drive_data; /* use by tuneproc/selectproc */
|
||||
unsigned int usage; /* current "open()" count for drive */
|
||||
unsigned int failures; /* current failure count */
|
||||
unsigned int max_failures; /* maximum allowed failure count */
|
||||
u64 probed_capacity;/* initial reported media capacity (ide-cd only currently) */
|
||||
@ -736,23 +735,22 @@ typedef struct hwif_s {
|
||||
int (*ide_dma_end)(ide_drive_t *drive);
|
||||
int (*ide_dma_check)(ide_drive_t *drive);
|
||||
int (*ide_dma_on)(ide_drive_t *drive);
|
||||
int (*ide_dma_off_quietly)(ide_drive_t *drive);
|
||||
void (*dma_off_quietly)(ide_drive_t *drive);
|
||||
int (*ide_dma_test_irq)(ide_drive_t *drive);
|
||||
int (*ide_dma_host_on)(ide_drive_t *drive);
|
||||
int (*ide_dma_host_off)(ide_drive_t *drive);
|
||||
void (*ide_dma_clear_irq)(ide_drive_t *drive);
|
||||
void (*dma_host_on)(ide_drive_t *drive);
|
||||
void (*dma_host_off)(ide_drive_t *drive);
|
||||
int (*ide_dma_lostirq)(ide_drive_t *drive);
|
||||
int (*ide_dma_timeout)(ide_drive_t *drive);
|
||||
|
||||
void (*OUTB)(u8 addr, unsigned long port);
|
||||
void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port);
|
||||
void (*OUTW)(u16 addr, unsigned long port);
|
||||
void (*OUTL)(u32 addr, unsigned long port);
|
||||
void (*OUTSW)(unsigned long port, void *addr, u32 count);
|
||||
void (*OUTSL)(unsigned long port, void *addr, u32 count);
|
||||
|
||||
u8 (*INB)(unsigned long port);
|
||||
u16 (*INW)(unsigned long port);
|
||||
u32 (*INL)(unsigned long port);
|
||||
void (*INSW)(unsigned long port, void *addr, u32 count);
|
||||
void (*INSL)(unsigned long port, void *addr, u32 count);
|
||||
|
||||
@ -774,7 +772,6 @@ typedef struct hwif_s {
|
||||
unsigned int cursg;
|
||||
unsigned int cursg_ofs;
|
||||
|
||||
int mmio; /* hosts iomio (0) or custom (2) select */
|
||||
int rqsize; /* max sectors per request */
|
||||
int irq; /* our irq number */
|
||||
|
||||
@ -802,12 +799,11 @@ typedef struct hwif_s {
|
||||
unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
|
||||
unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */
|
||||
unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
|
||||
unsigned no_dsc : 1; /* 0 default, 1 dsc_overlap disabled */
|
||||
unsigned auto_poll : 1; /* supports nop auto-poll */
|
||||
unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */
|
||||
unsigned no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */
|
||||
unsigned err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */
|
||||
unsigned atapi_irq_bogon : 1; /* Generates spurious DMA interrupts in PIO mode */
|
||||
unsigned mmio : 1; /* host uses MMIO */
|
||||
|
||||
struct device gendev;
|
||||
struct completion gendev_rel_comp; /* To deal with device release() */
|
||||
@ -1280,8 +1276,9 @@ int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *);
|
||||
int __ide_dma_bad_drive(ide_drive_t *);
|
||||
int __ide_dma_good_drive(ide_drive_t *);
|
||||
int ide_use_dma(ide_drive_t *);
|
||||
int __ide_dma_off(ide_drive_t *);
|
||||
void ide_dma_off(ide_drive_t *);
|
||||
void ide_dma_verbose(ide_drive_t *);
|
||||
int ide_set_dma(ide_drive_t *);
|
||||
ide_startstop_t ide_dma_intr(ide_drive_t *);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
|
||||
@ -1291,9 +1288,9 @@ extern void ide_destroy_dmatable(ide_drive_t *);
|
||||
extern int ide_release_dma(ide_hwif_t *);
|
||||
extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
|
||||
|
||||
extern int __ide_dma_host_off(ide_drive_t *);
|
||||
extern int __ide_dma_off_quietly(ide_drive_t *);
|
||||
extern int __ide_dma_host_on(ide_drive_t *);
|
||||
void ide_dma_host_off(ide_drive_t *);
|
||||
void ide_dma_off_quietly(ide_drive_t *);
|
||||
void ide_dma_host_on(ide_drive_t *);
|
||||
extern int __ide_dma_on(ide_drive_t *);
|
||||
extern int __ide_dma_check(ide_drive_t *);
|
||||
extern int ide_dma_setup(ide_drive_t *);
|
||||
@ -1305,8 +1302,9 @@ extern int __ide_dma_timeout(ide_drive_t *);
|
||||
|
||||
#else
|
||||
static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
|
||||
static inline int __ide_dma_off(ide_drive_t *drive) { return 0; }
|
||||
static inline void ide_dma_off(ide_drive_t *drive) { ; }
|
||||
static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
|
||||
static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
|
||||
#endif /* CONFIG_BLK_DEV_IDEDMA */
|
||||
|
||||
#ifndef CONFIG_BLK_DEV_IDEDMA_PCI
|
||||
@ -1354,6 +1352,7 @@ extern int ide_dma_enable(ide_drive_t *drive);
|
||||
extern char *ide_xfer_verbose(u8 xfer_rate);
|
||||
extern void ide_toggle_bounce(ide_drive_t *drive, int on);
|
||||
extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
|
||||
int ide_use_fast_pio(ide_drive_t *);
|
||||
|
||||
u8 ide_dump_status(ide_drive_t *, const char *, u8);
|
||||
|
||||
@ -1367,7 +1366,6 @@ typedef struct ide_pio_data_s {
|
||||
u8 pio_mode;
|
||||
u8 use_iordy;
|
||||
u8 overridden;
|
||||
u8 blacklisted;
|
||||
unsigned int cycle_time;
|
||||
} ide_pio_data_t;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user