Commit acff0d93 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.15 IDE 64

Let's just get over with  this before queue handling will be targeted again...

- Implement suggestions by Russell King for improved portability and separation
   between PCI and non PCI host code.

- pdc202xxx updates from Thierry Vignaud.

- Tiny PIO fix from Tomita.
parent d7e09f7e
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
O_TARGET := idedriver.o O_TARGET := idedriver.o
export-objs := ide-taskfile.o ide.o ide-features.o ide-probe.o ide-dma.o ataraid.o export-objs := ide-taskfile.o ide.o ide-features.o ide-probe.o quirks.o pcidma.o ataraid.o
obj-y := obj-y :=
obj-m := obj-m :=
...@@ -43,7 +43,8 @@ ide-obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o ...@@ -43,7 +43,8 @@ ide-obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
ide-obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o ide-obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o
ide-obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o ide-obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o
ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI) += ide-dma.o ide-obj-$(CONFIG_BLK_DEV_IDEDMA) += quirks.o
ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI) += pcidma.o
ide-obj-$(CONFIG_BLK_DEV_IDE_TCQ) += tcq.o ide-obj-$(CONFIG_BLK_DEV_IDE_TCQ) += tcq.o
ide-obj-$(CONFIG_PCI) += ide-pci.o ide-obj-$(CONFIG_PCI) += ide-pci.o
ide-obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o ide-obj-$(CONFIG_BLK_DEV_ISAPNP) += ide-pnp.o
......
...@@ -562,7 +562,7 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r ...@@ -562,7 +562,7 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r
if (!ide_end_request(drive, rq, 1)) if (!ide_end_request(drive, rq, 1))
return ide_stopped; return ide_stopped;
if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) { if ((rq->nr_sectors == 1) != (stat & DRQ_STAT)) {
pBuf = ide_map_rq(rq, &flags); pBuf = ide_map_rq(rq, &flags);
DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors); DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);
......
...@@ -1145,7 +1145,7 @@ static unsigned long longest_sleep(struct ata_channel *channel) ...@@ -1145,7 +1145,7 @@ static unsigned long longest_sleep(struct ata_channel *channel)
} }
/* /*
* Select the next device which will be serviced. This selects onlt between * Select the next device which will be serviced. This selects only between
* devices on the same channel, since everything else will be scheduled on the * devices on the same channel, since everything else will be scheduled on the
* queue level. * queue level.
*/ */
......
...@@ -10,10 +10,6 @@ ...@@ -10,10 +10,6 @@
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. * 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., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/* /*
......
This diff is collapsed.
/**** vi:set ts=8 sts=8 sw=8:************************************************
*
* Copyright (C) 2002 Marcin Dalecki <martin@dalecki.de>
*
* Copyright (c) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (c) 1995-1998 Mark Lord
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
/*
* Just the black and white list handling for BM-DMA operation.
*/
#include <linux/config.h>
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
#ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS
struct drive_list_entry {
char * id_model;
char * id_firmware;
};
struct drive_list_entry drive_whitelist[] = {
{ "Micropolis 2112A", NULL },
{ "CONNER CTMA 4000", NULL },
{ "CONNER CTT8000-A", NULL },
{ "ST34342A", NULL },
{ NULL, NULL }
};
struct drive_list_entry drive_blacklist[] = {
{ "WDC AC11000H", NULL },
{ "WDC AC22100H", NULL },
{ "WDC AC32500H", NULL },
{ "WDC AC33100H", NULL },
{ "WDC AC31600H", NULL },
{ "WDC AC32100H", "24.09P07" },
{ "WDC AC23200L", "21.10N21" },
{ "Compaq CRD-8241B", NULL },
{ "CRD-8400B", NULL },
{ "CRD-8480B", NULL },
{ "CRD-8480C", NULL },
{ "CRD-8482B", NULL },
{ "CRD-84", NULL },
{ "SanDisk SDP3B", NULL },
{ "SanDisk SDP3B-64", NULL },
{ "SANYO CD-ROM CRD", NULL },
{ "HITACHI CDR-8", NULL },
{ "HITACHI CDR-8335", NULL },
{ "HITACHI CDR-8435", NULL },
{ "Toshiba CD-ROM XM-6202B", NULL },
{ "CD-532E-A", NULL },
{ "E-IDE CD-ROM CR-840", NULL },
{ "CD-ROM Drive/F5A", NULL },
{ "RICOH CD-R/RW MP7083A", NULL },
{ "WPI CDD-820", NULL },
{ "SAMSUNG CD-ROM SC-148C", NULL },
{ "SAMSUNG CD-ROM SC-148F", NULL },
{ "SAMSUNG CD-ROM SC", NULL },
{ "SanDisk SDP3B-64", NULL },
{ "SAMSUNG CD-ROM SN-124", NULL },
{ "PLEXTOR CD-R PX-W8432T", NULL },
{ "ATAPI CD-ROM DRIVE 40X MAXIMUM", NULL },
{ "_NEC DV5800A", NULL },
{ NULL, NULL }
};
static int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_table)
{
for ( ; drive_table->id_model ; drive_table++)
if ((!strcmp(drive_table->id_model, id->model)) &&
((drive_table->id_firmware && !strstr(drive_table->id_firmware, id->fw_rev)) ||
(!drive_table->id_firmware)))
return 1;
return 0;
}
#else
/*
* good_dma_drives() lists the model names (from "hdparm -i")
* of drives which do not support mode2 DMA but which are
* known to work fine with this interface under Linux.
*/
const char *good_dma_drives[] = {"Micropolis 2112A",
"CONNER CTMA 4000",
"CONNER CTT8000-A",
"ST34342A", /* for Sun Ultra */
NULL};
/*
* bad_dma_drives() lists the model names (from "hdparm -i")
* of drives which supposedly support (U)DMA but which are
* known to corrupt data with this interface under Linux.
*
* This is an empirical list. Its generated from bug reports. That means
* while it reflects actual problem distributions it doesn't answer whether
* the drive or the controller, or cabling, or software, or some combination
* thereof is the fault. If you don't happen to agree with the kernel's
* opinion of your drive - use hdparm to turn DMA on.
*/
const char *bad_dma_drives[] = {"WDC AC11000H",
"WDC AC22100H",
"WDC AC32100H",
"WDC AC32500H",
"WDC AC33100H",
"WDC AC31600H",
NULL};
#endif
/*
* For both Blacklisted and Whitelisted drives.
* This is setup to be called as an extern for future support
* to other special driver code.
*/
int check_drive_lists(struct ata_device *drive, int good_bad)
{
struct hd_driveid *id = drive->id;
#ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS
if (good_bad) {
return in_drive_list(id, drive_whitelist);
} else {
int blacklist = in_drive_list(id, drive_blacklist);
if (blacklist)
printk("%s: Disabling (U)DMA for %s\n", drive->name, id->model);
return(blacklist);
}
#else
const char **list;
if (good_bad) {
/* Consult the list of known "good" drives */
list = good_dma_drives;
while (*list) {
if (!strcmp(*list++,id->model))
return 1;
}
} else {
/* Consult the list of known "bad" drives */
list = bad_dma_drives;
while (*list) {
if (!strcmp(*list++,id->model)) {
printk("%s: Disabling (U)DMA for %s\n",
drive->name, id->model);
return 1;
}
}
}
#endif
return 0;
}
void udma_print(struct ata_device *drive)
{
#ifdef CONFIG_ARCH_ACORN
printk(", DMA");
#else
struct hd_driveid *id = drive->id;
char *str = NULL;
if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
(id->dma_ultra & (id->dma_ultra >> 14) & 3)) {
if ((id->dma_ultra >> 15) & 1)
str = ", UDMA(mode 7)"; /* UDMA BIOS-enabled! */
else
str = ", UDMA(133)"; /* UDMA BIOS-enabled! */
} else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
(id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
if ((id->dma_ultra >> 13) & 1) {
str = ", UDMA(100)"; /* UDMA BIOS-enabled! */
} else if ((id->dma_ultra >> 12) & 1) {
str = ", UDMA(66)"; /* UDMA BIOS-enabled! */
} else {
str = ", UDMA(44)"; /* UDMA BIOS-enabled! */
}
} else if ((id->field_valid & 4) &&
(id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
if ((id->dma_ultra >> 10) & 1) {
str = ", UDMA(33)"; /* UDMA BIOS-enabled! */
} else if ((id->dma_ultra >> 9) & 1) {
str = ", UDMA(25)"; /* UDMA BIOS-enabled! */
} else {
str = ", UDMA(16)"; /* UDMA BIOS-enabled! */
}
} else if (id->field_valid & 4)
str = ", (U)DMA"; /* Can be BIOS-enabled! */
else
str = ", DMA";
printk(str);
#endif
}
/*
* Drive back/white list handling for UDMA capability:
*/
int udma_black_list(struct ata_device *drive)
{
return check_drive_lists(drive, 0);
}
int udma_white_list(struct ata_device *drive)
{
return check_drive_lists(drive, 1);
}
EXPORT_SYMBOL(udma_print);
EXPORT_SYMBOL(udma_black_list);
EXPORT_SYMBOL(udma_white_list);
...@@ -820,22 +820,55 @@ extern int ide_unregister_subdriver(struct ata_device *drive); ...@@ -820,22 +820,55 @@ extern int ide_unregister_subdriver(struct ata_device *drive);
void __init ide_scan_pcibus(int scan_direction); void __init ide_scan_pcibus(int scan_direction);
#endif #endif
static inline void udma_enable(struct ata_device *drive, int on, int verbose)
{
drive->channel->udma_enable(drive, on, verbose);
}
static inline int udma_start(struct ata_device *drive, struct request *rq)
{
return drive->channel->udma_start(drive, rq);
}
static inline int udma_stop(struct ata_device *drive)
{
return drive->channel->udma_stop(drive);
}
static inline int udma_read(struct ata_device *drive, struct request *rq)
{
return drive->channel->udma_read(drive, rq);
}
static inline int udma_write(struct ata_device *drive, struct request *rq)
{
return drive->channel->udma_write(drive, rq);
}
static inline int udma_irq_status(struct ata_device *drive)
{
return drive->channel->udma_irq_status(drive);
}
static inline void udma_timeout(struct ata_device *drive)
{
return drive->channel->udma_timeout(drive);
}
static inline void udma_irq_lost(struct ata_device *drive)
{
return drive->channel->udma_irq_lost(drive);
}
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
extern int udma_new_table(struct ata_channel *, struct request *); extern int udma_new_table(struct ata_channel *, struct request *);
extern void udma_destroy_table(struct ata_channel *); extern void udma_destroy_table(struct ata_channel *);
extern void udma_print(struct ata_device *); extern void udma_print(struct ata_device *);
extern void udma_enable(struct ata_device *, int, int);
extern int udma_black_list(struct ata_device *); extern int udma_black_list(struct ata_device *);
extern int udma_white_list(struct ata_device *); extern int udma_white_list(struct ata_device *);
extern void udma_timeout(struct ata_device *);
extern void udma_irq_lost(struct ata_device *);
extern int udma_start(struct ata_device *, struct request *rq);
extern int udma_stop(struct ata_device *);
extern int udma_read(struct ata_device *, struct request *rq);
extern int udma_write(struct ata_device *, struct request *rq);
extern int udma_irq_status(struct ata_device *);
extern int ata_do_udma(unsigned int reading, struct ata_device *drive, struct request *rq); extern int ata_do_udma(unsigned int reading, struct ata_device *drive, struct request *rq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment