Commit 0c0a9d38 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.8 IDE 37

- Don't abuse the sense field for passing failed packet_commands in struct
   packet_command use a new field instead.

- Apply minor bits forwarded by Dave Jones to me.

- Fix ide_raw_taskfile() to flag the ar used there to be no subject of free_req
   list management. This solvs the "hang after /proc/ide read" problem, which
   was in fact a memory corruption problem.
parent 87689e36
...@@ -160,7 +160,7 @@ CONFIG_BLK_DEV_IDESCSI ...@@ -160,7 +160,7 @@ CONFIG_BLK_DEV_IDESCSI
you can then use this emulation together with an appropriate SCSI you can then use this emulation together with an appropriate SCSI
device driver. In order to do this, say Y here and to "SCSI support" device driver. In order to do this, say Y here and to "SCSI support"
and "SCSI generic support", below. You must then provide the kernel and "SCSI generic support", below. You must then provide the kernel
command line "hdx=scsi" (try "man bootparam" or see the command line "hdx=ide-scsi" (try "man bootparam" or see the
documentation of your boot loader (lilo or loadlin) about how to documentation of your boot loader (lilo or loadlin) about how to
pass options to the kernel at boot time) for devices if you want the pass options to the kernel at boot time) for devices if you want the
native EIDE sub-drivers to skip over the native support, so that native EIDE sub-drivers to skip over the native support, so that
...@@ -543,13 +543,13 @@ CONFIG_BLK_DEV_HT6560B ...@@ -543,13 +543,13 @@ CONFIG_BLK_DEV_HT6560B
CONFIG_BLK_DEV_PDC4030 CONFIG_BLK_DEV_PDC4030
This driver provides support for the secondary IDE interface and This driver provides support for the secondary IDE interface and
cache of Promise IDE chipsets, e.g. DC4030 and DC5030. This driver cache of the original Promise IDE chipsets, e.g. DC4030 and DC5030.
is known to incur timeouts/retries during heavy I/O to drives It is nothing to do with the later range of Promise UDMA chipsets -
attached to the secondary interface. CD-ROM and TAPE devices are see the PDC_202XX support for these. CD-ROM and TAPE devices are not
not supported yet. This driver is enabled at runtime using the supported (and probably never will be since I don't think the cards
"ide0=dc4030" kernel boot parameter. See the support them). This driver is enabled at runtime using the "ide0=dc4030"
<file:Documentation/ide.txt> and <file:drivers/ide/pdc4030.c> files or "ide1=dc4030" kernel boot parameter. See the
for more info. <file:drivers/ide/pdc4030.c> file for more info.
CONFIG_BLK_DEV_QD65XX CONFIG_BLK_DEV_QD65XX
This driver is enabled at runtime using the "ide0=qd65xx" kernel This driver is enabled at runtime using the "ide0=qd65xx" kernel
...@@ -629,6 +629,11 @@ CONFIG_BLK_DEV_MAC_IDE ...@@ -629,6 +629,11 @@ CONFIG_BLK_DEV_MAC_IDE
devices (hard disks, CD-ROM drives, etc.) that are connected to the devices (hard disks, CD-ROM drives, etc.) that are connected to the
builtin IDE interface. builtin IDE interface.
CONFIG_BLK_DEV_Q40IDE
Enable the on-board IDE controller in the Q40/Q60. This should
normally be on; disable it only if you are running a custom hard
drive subsystem through an expansion card.
CONFIG_BLK_DEV_IDE_ICSIDE CONFIG_BLK_DEV_IDE_ICSIDE
On Acorn systems, say Y here if you wish to use the ICS IDE On Acorn systems, say Y here if you wish to use the ICS IDE
interface card. This is not required for ICS partition support. interface card. This is not required for ICS partition support.
......
...@@ -337,7 +337,9 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, struct request *rq) ...@@ -337,7 +337,9 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, struct request *rq)
int log = 0; int log = 0;
/* FIXME --mdcki */ /* FIXME --mdcki */
struct packet_command *pc = (struct packet_command *) rq->special; struct packet_command *pc = (struct packet_command *) rq->special;
struct packet_command *failed_command = (struct packet_command *) pc->sense; struct packet_command *failed_command = pc->failed_command;
/* Decode sense data from drive */
struct request_sense *sense = (struct request_sense *) (pc->buffer - rq->cmd[4]); struct request_sense *sense = (struct request_sense *) (pc->buffer - rq->cmd[4]);
unsigned char fail_cmd; unsigned char fail_cmd;
...@@ -526,10 +528,10 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, ...@@ -526,10 +528,10 @@ static void cdrom_queue_request_sense(ide_drive_t *drive,
if (sense == NULL) if (sense == NULL)
sense = &info->sense_data; sense = &info->sense_data;
memset(pc, 0, sizeof(struct packet_command)); memset(pc, 0, sizeof(*pc));
pc->buffer = (void *) sense; pc->buffer = (void *) sense;
pc->buflen = 18; pc->buflen = 18;
pc->sense = (struct request_sense *) failed_command; pc->failed_command = failed_command;
/* stuff the sense request in front of our current request */ /* stuff the sense request in front of our current request */
rq = &info->request_sense_request; rq = &info->request_sense_request;
...@@ -598,6 +600,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, ...@@ -598,6 +600,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
pc->stat = 1; pc->stat = 1;
cdrom_end_request(drive, 1); cdrom_end_request(drive, 1);
*startstop = ide_error (drive, "request sense failure", stat); *startstop = ide_error (drive, "request sense failure", stat);
return 1; return 1;
} else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) { } else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
/* All other functions, except for READ. */ /* All other functions, except for READ. */
...@@ -635,6 +638,10 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, ...@@ -635,6 +638,10 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
pc->stat = 1; pc->stat = 1;
cdrom_end_request(drive, 1); cdrom_end_request(drive, 1);
/* FIXME: this is the only place where pc->sense get's used.
* Think hard about how to get rid of it...
*/
if ((stat & ERR_STAT) != 0) if ((stat & ERR_STAT) != 0)
cdrom_queue_request_sense(drive, wait, pc->sense, pc); cdrom_queue_request_sense(drive, wait, pc->sense, pc);
} else if (rq->flags & REQ_CMD) { } else if (rq->flags & REQ_CMD) {
...@@ -728,27 +735,26 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, ...@@ -728,27 +735,26 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
return startstop; return startstop;
if (info->dma) { if (info->dma) {
if (info->cmd == READ) { if (info->cmd == READ)
info->dma = !drive->channel->dmaproc(ide_dma_read, drive); info->dma = !drive->channel->dmaproc(ide_dma_read, drive);
} else if (info->cmd == WRITE) { else if (info->cmd == WRITE)
info->dma = !drive->channel->dmaproc(ide_dma_write, drive); info->dma = !drive->channel->dmaproc(ide_dma_write, drive);
} else { else
printk("ide-cd: DMA set, but not allowed\n"); printk("ide-cd: DMA set, but not allowed\n");
}
} }
/* Set up the controller registers. */ /* Set up the controller registers. */
OUT_BYTE (info->dma, IDE_FEATURE_REG); OUT_BYTE(info->dma, IDE_FEATURE_REG);
OUT_BYTE (0, IDE_NSECTOR_REG); OUT_BYTE(0, IDE_NSECTOR_REG);
OUT_BYTE (0, IDE_SECTOR_REG); OUT_BYTE(0, IDE_SECTOR_REG);
OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG); OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG);
OUT_BYTE (xferlen >> 8 , IDE_HCYL_REG); OUT_BYTE(xferlen >> 8 , IDE_HCYL_REG);
if (IDE_CONTROL_REG) if (IDE_CONTROL_REG)
OUT_BYTE (drive->ctl, IDE_CONTROL_REG); OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
if (info->dma) if (info->dma)
(void) drive->channel->dmaproc(ide_dma_begin, drive); drive->channel->dmaproc(ide_dma_begin, drive);
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
BUG_ON(HWGROUP(drive)->handler); BUG_ON(HWGROUP(drive)->handler);
...@@ -1386,17 +1392,13 @@ void cdrom_sleep (int time) ...@@ -1386,17 +1392,13 @@ void cdrom_sleep (int time)
} }
static static
int cdrom_queue_packet_command(ide_drive_t *drive, unsigned char *cmd, struct packet_command *pc) int cdrom_queue_packet_command(ide_drive_t *drive, unsigned char *cmd,
struct request_sense *sense, struct packet_command *pc)
{ {
struct request_sense sense;
struct request rq; struct request rq;
int retries = 10; int retries = 10;
memcpy(rq.cmd, cmd, CDROM_PACKET_SIZE); memcpy(rq.cmd, cmd, CDROM_PACKET_SIZE);
if (pc->sense == NULL)
pc->sense = &sense;
/* Start of retry loop. */ /* Start of retry loop. */
do { do {
ide_init_drive_cmd(&rq); ide_init_drive_cmd(&rq);
...@@ -1408,18 +1410,25 @@ int cdrom_queue_packet_command(ide_drive_t *drive, unsigned char *cmd, struct pa ...@@ -1408,18 +1410,25 @@ int cdrom_queue_packet_command(ide_drive_t *drive, unsigned char *cmd, struct pa
if (ide_do_drive_cmd(drive, &rq, ide_wait)) { if (ide_do_drive_cmd(drive, &rq, ide_wait)) {
printk("%s: do_drive_cmd returned stat=%02x,err=%02x\n", printk("%s: do_drive_cmd returned stat=%02x,err=%02x\n",
drive->name, rq.buffer[0], rq.buffer[1]); drive->name, rq.buffer[0], rq.buffer[1]);
/* FIXME: we should probably abort/retry or something */ /* FIXME: we should probably abort/retry or something */
if (sense) {
/* Decode the error here at least for error
* reporting to upper layers.!
*/
}
} }
if (pc->stat != 0) { if (pc->stat != 0) {
/* The request failed. Retry if it was due to a unit /* The request failed. Retry if it was due to a unit
attention status attention status
(usually means media was changed). */ (usually means media was changed). */
struct request_sense *reqbuf = pc->sense;
if (reqbuf->sense_key == UNIT_ATTENTION) if (sense && sense->sense_key == UNIT_ATTENTION)
cdrom_saw_media_change (drive); cdrom_saw_media_change (drive);
else if (reqbuf->sense_key == NOT_READY && else if (sense && sense->sense_key == NOT_READY &&
reqbuf->asc == 4 && reqbuf->ascq != 4) { sense->asc == 4 && sense->ascq != 4) {
/* The drive is in the process of loading /* The drive is in the process of loading
a disk. Retry, but wait a little to give a disk. Retry, but wait a little to give
the drive time to complete the load. */ the drive time to complete the load. */
...@@ -1753,7 +1762,7 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) ...@@ -1753,7 +1762,7 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
cmd[7] = cdi->sanyo_slot % 3; cmd[7] = cdi->sanyo_slot % 3;
#endif #endif
return cdrom_queue_packet_command(drive, cmd, &pc); return cdrom_queue_packet_command(drive, cmd, sense, &pc);
} }
...@@ -1774,7 +1783,7 @@ cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense) ...@@ -1774,7 +1783,7 @@ cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense)
pc.sense = sense; pc.sense = sense;
cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
cmd[4] = lockflag ? 1 : 0; cmd[4] = lockflag ? 1 : 0;
stat = cdrom_queue_packet_command(drive, cmd, &pc); stat = cdrom_queue_packet_command(drive, cmd, sense, &pc);
} }
/* If we got an illegal field error, the drive /* If we got an illegal field error, the drive
...@@ -1819,7 +1828,7 @@ static int cdrom_eject(ide_drive_t *drive, int ejectflag, ...@@ -1819,7 +1828,7 @@ static int cdrom_eject(ide_drive_t *drive, int ejectflag,
cmd[0] = GPCMD_START_STOP_UNIT; cmd[0] = GPCMD_START_STOP_UNIT;
cmd[4] = 0x02 + (ejectflag != 0); cmd[4] = 0x02 + (ejectflag != 0);
return cdrom_queue_packet_command(drive, cmd, &pc); return cdrom_queue_packet_command(drive, cmd, sense, &pc);
} }
static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
...@@ -1840,7 +1849,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, ...@@ -1840,7 +1849,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
cmd[0] = GPCMD_READ_CDVD_CAPACITY; cmd[0] = GPCMD_READ_CDVD_CAPACITY;
pc.buffer = (char *)&capbuf; pc.buffer = (char *)&capbuf;
pc.buflen = sizeof(capbuf); pc.buflen = sizeof(capbuf);
stat = cdrom_queue_packet_command(drive, cmd, &pc); stat = cdrom_queue_packet_command(drive, cmd, sense, &pc);
if (stat == 0) if (stat == 0)
*capacity = 1 + be32_to_cpu(capbuf.lba); *capacity = 1 + be32_to_cpu(capbuf.lba);
...@@ -1869,7 +1878,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, ...@@ -1869,7 +1878,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
cmd[8] = (buflen & 0xff); cmd[8] = (buflen & 0xff);
cmd[9] = (format << 6); cmd[9] = (format << 6);
return cdrom_queue_packet_command(drive, cmd, &pc); return cdrom_queue_packet_command(drive, cmd, sense, &pc);
} }
...@@ -2046,7 +2055,7 @@ static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf, ...@@ -2046,7 +2055,7 @@ static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf,
cmd[7] = (buflen >> 8); cmd[7] = (buflen >> 8);
cmd[8] = (buflen & 0xff); cmd[8] = (buflen & 0xff);
return cdrom_queue_packet_command(drive, cmd, &pc); return cdrom_queue_packet_command(drive, cmd, sense, &pc);
} }
/* ATAPI cdrom drives are free to select the speed you request or any slower /* ATAPI cdrom drives are free to select the speed you request or any slower
...@@ -2078,7 +2087,7 @@ static int cdrom_select_speed(ide_drive_t *drive, int speed, ...@@ -2078,7 +2087,7 @@ static int cdrom_select_speed(ide_drive_t *drive, int speed,
cmd[5] = speed & 0xff; cmd[5] = speed & 0xff;
} }
return cdrom_queue_packet_command(drive, cmd, &pc); return cdrom_queue_packet_command(drive, cmd, sense, &pc);
} }
static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end) static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end)
...@@ -2094,7 +2103,7 @@ static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end) ...@@ -2094,7 +2103,7 @@ static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end)
lba_to_msf(lba_start, &cmd[3], &cmd[4], &cmd[5]); lba_to_msf(lba_start, &cmd[3], &cmd[4], &cmd[5]);
lba_to_msf(lba_end-1, &cmd[6], &cmd[7], &cmd[8]); lba_to_msf(lba_end-1, &cmd[6], &cmd[7], &cmd[8]);
return cdrom_queue_packet_command(drive, cmd, &pc); return cdrom_queue_packet_command(drive, cmd, &sense, &pc);
} }
static int cdrom_get_toc_entry(ide_drive_t *drive, int track, static int cdrom_get_toc_entry(ide_drive_t *drive, int track,
...@@ -2143,7 +2152,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi, ...@@ -2143,7 +2152,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
pc.quiet = cgc->quiet; pc.quiet = cgc->quiet;
pc.timeout = cgc->timeout; pc.timeout = cgc->timeout;
pc.sense = cgc->sense; pc.sense = cgc->sense;
cgc->stat = cdrom_queue_packet_command(drive, cgc->cmd, &pc); cgc->stat = cdrom_queue_packet_command(drive, cgc->cmd, cgc->sense, &pc);
if (!cgc->stat) if (!cgc->stat)
cgc->buflen -= pc.buflen; cgc->buflen -= pc.buflen;
......
...@@ -104,6 +104,15 @@ struct packet_command { ...@@ -104,6 +104,15 @@ struct packet_command {
int quiet; int quiet;
int timeout; int timeout;
struct request_sense *sense; struct request_sense *sense;
/* This is currently used to pass failed commands through the request
* queue. Is this for asynchronos error reporting?
*
* Can we always be sure that this didn't valish from stack beneath us
* - we can't!
*/
struct packet_command *failed_command;
}; };
/* Structure of a MSF cdrom address. */ /* Structure of a MSF cdrom address. */
......
...@@ -372,10 +372,10 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq, ...@@ -372,10 +372,10 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq,
} }
/* Teardown mappings after DMA has completed. */ /* Teardown mappings after DMA has completed. */
void ide_destroy_dmatable (ide_drive_t *drive) void ide_destroy_dmatable(struct ata_device *d)
{ {
struct pci_dev *dev = drive->channel->pci_dev; struct pci_dev *dev = d->channel->pci_dev;
struct ata_request *ar = IDE_CUR_AR(drive); struct ata_request *ar = IDE_CUR_AR(d);
pci_unmap_sg(dev, ar->ar_sg_table, ar->ar_sg_nents, ar->ar_sg_ddir); pci_unmap_sg(dev, ar->ar_sg_table, ar->ar_sg_nents, ar->ar_sg_ddir);
} }
......
/* /*
* linux/drivers/ide/ide-floppy.c Version 0.97.sv Jan 14 2001 * linux/drivers/ide/ide-floppy.c Version 0.99 Feb 24 2002
* *
* Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il> * Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
* Copyright (C) 2000 - 2001 Paul Bristow <paul@paulbristow.net> * Copyright (C) 2000 - 2002 Paul Bristow <paul@paulbristow.net>
*/ */
/* /*
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* This driver supports the following IDE floppy drives: * This driver supports the following IDE floppy drives:
* *
* LS-120 SuperDisk * LS-120/240 SuperDisk
* Iomega Zip 100/250 * Iomega Zip 100/250
* Iomega PC Card Clik!/PocketZip * Iomega PC Card Clik!/PocketZip
* *
...@@ -76,9 +76,11 @@ ...@@ -76,9 +76,11 @@
* bit was being deasserted by my IOMEGA ATAPI ZIP 100 * bit was being deasserted by my IOMEGA ATAPI ZIP 100
* drive before the drive was actually ready. * drive before the drive was actually ready.
* Ver 0.98a Oct 29 01 Expose delay value so we can play. * Ver 0.98a Oct 29 01 Expose delay value so we can play.
* Ver 0.99 Feb 24 02 Remove duplicate code, modify clik! detection code
* to support new PocketZip drives
*/ */
#define IDEFLOPPY_VERSION "0.98a" #define IDEFLOPPY_VERSION "0.99"
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -1070,8 +1072,8 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) ...@@ -1070,8 +1072,8 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive)
*/ */
BUG_ON(HWGROUP(drive)->handler); BUG_ON(HWGROUP(drive)->handler);
ide_set_handler (drive, ide_set_handler (drive,
&idefloppy_pc_intr, /* service routine for packet command */ &idefloppy_pc_intr, /* service routine for packet command */
floppy->ticks, /* wait this long before "failing" */ floppy->ticks, /* wait this long before "failing" */
&idefloppy_transfer_pc2); /* fail == transfer_pc2 */ &idefloppy_transfer_pc2); /* fail == transfer_pc2 */
return ide_started; return ide_started;
...@@ -2005,7 +2007,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) ...@@ -2005,7 +2007,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
* above fix. It makes nasty clicking noises without * above fix. It makes nasty clicking noises without
* it, so please don't remove this. * it, so please don't remove this.
*/ */
if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0) { if (strncmp(drive->id->model, "IOMEGA Clik!", 11) == 0) {
blk_queue_max_sectors(&drive->queue, 64); blk_queue_max_sectors(&drive->queue, 64);
set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags); set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags);
} }
......
/* /*
*
*
* linux/drivers/ide/ide-m8xx.c * linux/drivers/ide/ide-m8xx.c
* *
* Copyright (C) 2000, 2001 Wolfgang Denk, wd@denx.de
* Modified for direct IDE interface
* by Thomas Lange, thomas@corelatus.com
* Modified for direct IDE interface on 8xx without using the PCMCIA
* controller
* by Steven.Scholz@imc-berlin.de
* Moved out of arch/ppc/kernel/m8xx_setup.c, other minor cleanups
* by Mathew Locke <mattl@mvista.com>
*/ */
#include <linux/config.h> #include <linux/config.h>
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#define DEBUG_TASKFILE 0 /* unset when fixed */ #define DEBUG_TASKFILE 0 /* unset when fixed */
#if DEBUG_TASKFILE #if DEBUG_TASKFILE
#define DTF(x...) printk(x) #define DTF(x...) printk(##x)
#else #else
#define DTF(x...) #define DTF(x...)
#endif #endif
...@@ -901,20 +901,25 @@ void init_taskfile_request(struct request *rq) ...@@ -901,20 +901,25 @@ void init_taskfile_request(struct request *rq)
int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf) int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
{ {
struct request rq; struct request rq;
struct ata_request ar; struct ata_request star;
ata_ar_init(drive, &star);
/* Don't put this request on free_req list after usage.
*/
star.ar_flags |= ATA_AR_STATIC;
ata_ar_init(drive, &ar);
init_taskfile_request(&rq); init_taskfile_request(&rq);
rq.buffer = buf; rq.buffer = buf;
memcpy(&ar.ar_task, args, sizeof(*args)); memcpy(&star.ar_task, args, sizeof(*args));
if (args->command_type != IDE_DRIVE_TASK_NO_DATA) if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
rq.current_nr_sectors = rq.nr_sectors rq.current_nr_sectors = rq.nr_sectors
= (args->hobfile.sector_count << 8) = (args->hobfile.sector_count << 8)
| args->taskfile.sector_count; | args->taskfile.sector_count;
rq.special = &ar; rq.special = &star;
return ide_do_drive_cmd(drive, &rq, ide_wait); return ide_do_drive_cmd(drive, &rq, ide_wait);
} }
......
...@@ -1729,20 +1729,23 @@ static void unexpected_intr(int irq, ide_hwgroup_t *hwgroup) ...@@ -1729,20 +1729,23 @@ static void unexpected_intr(int irq, ide_hwgroup_t *hwgroup)
* handle the unexpected interrupt * handle the unexpected interrupt
*/ */
do { do {
if (hwif->irq == irq) { if (hwif->irq != irq)
stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]); continue;
if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
/* Try to not flood the console with msgs */ stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);
static unsigned long last_msgtime, count; if (!OK_STAT(stat, READY_STAT, BAD_STAT)) {
++count; /* Try to not flood the console with msgs */
if (0 < (signed long)(jiffies - (last_msgtime + HZ))) { static unsigned long last_msgtime;
last_msgtime = jiffies; static int count;
printk("%s%s: unexpected interrupt, status=0x%02x, count=%ld\n", ++count;
hwif->name, (hwif->next == hwgroup->hwif) ? "" : "(?)", stat, count); if (time_after(jiffies, last_msgtime + HZ)) {
} last_msgtime = jiffies;
printk("%s%s: unexpected interrupt, status=0x%02x, count=%d\n",
hwif->name, (hwif->next == hwgroup->hwif) ? "" : "(?)", stat, count);
} }
} }
} while ((hwif = hwif->next) != hwgroup->hwif); hwif = hwif->next;
} while (hwif != hwgroup->hwif);
} }
/* /*
...@@ -1764,7 +1767,8 @@ void ide_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1764,7 +1767,8 @@ void ide_intr(int irq, void *dev_id, struct pt_regs *regs)
goto out_lock; goto out_lock;
if ((handler = hwgroup->handler) == NULL || hwgroup->poll_timeout != 0) { if ((handler = hwgroup->handler) == NULL || hwgroup->poll_timeout != 0) {
printk("ide: unexpected interrupt\n"); printk(KERN_INFO "ide: unexpected interrupt %d %d\n", hwif->unit, irq);
/* /*
* Not expecting an interrupt from this drive. * Not expecting an interrupt from this drive.
* That means this could be: * That means this could be:
......
...@@ -50,7 +50,7 @@ static void it8172_tune_drive (ide_drive_t *drive, byte pio); ...@@ -50,7 +50,7 @@ static void it8172_tune_drive (ide_drive_t *drive, byte pio);
#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IT8172_TUNING) #if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IT8172_TUNING)
static byte it8172_dma_2_pio (byte xfer_rate); static byte it8172_dma_2_pio (byte xfer_rate);
static int it8172_tune_chipset (ide_drive_t *drive, byte speed); static int it8172_tune_chipset (ide_drive_t *drive, byte speed);
static int it8172_config_drive_for_dma (ide_drive_t *drive); static int it8172_config_chipset_for_dma (ide_drive_t *drive);
static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive); static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
#endif #endif
void __init ide_init_it8172(struct ata_channel *channel); void __init ide_init_it8172(struct ata_channel *channel);
...@@ -59,16 +59,14 @@ void __init ide_init_it8172(struct ata_channel *channel); ...@@ -59,16 +59,14 @@ void __init ide_init_it8172(struct ata_channel *channel);
static void it8172_tune_drive (ide_drive_t *drive, byte pio) static void it8172_tune_drive (ide_drive_t *drive, byte pio)
{ {
unsigned long flags; unsigned long flags;
u16 master_data; u16 drive_enables;
u32 slave_data; u32 drive_timing;
int is_slave = (&drive->channel->drives[1] == drive); int is_slave = (&drive->channel->drives[1] == drive);
int master_port = 0x40;
int slave_port = 0x44; if (pio == 255)
pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
if (pio == 255) else
pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; pio = min_t(byte, pio, 4);
else
pio = min_t(byte, pio, 4);
pci_read_config_word(drive->channel->pci_dev, master_port, &master_data); pci_read_config_word(drive->channel->pci_dev, master_port, &master_data);
pci_read_config_dword(drive->channel->pci_dev, slave_port, &slave_data); pci_read_config_dword(drive->channel->pci_dev, slave_port, &slave_data);
...@@ -77,19 +75,27 @@ static void it8172_tune_drive (ide_drive_t *drive, byte pio) ...@@ -77,19 +75,27 @@ static void it8172_tune_drive (ide_drive_t *drive, byte pio)
* FIX! The DIOR/DIOW pulse width and recovery times in port 0x44 * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
* are being left at the default values of 8 PCI clocks (242 nsec * are being left at the default values of 8 PCI clocks (242 nsec
* for a 33 MHz clock). These can be safely shortened at higher * for a 33 MHz clock). These can be safely shortened at higher
* PIO modes. * PIO modes. The DIOR/DIOW pulse width and recovery times only
* apply to PIO modes, not to the DMA modes.
*/ */
/*
* Enable port 0x44. The IT8172G spec is confused; it calls
* this register the "Slave IDE Timing Register", but in fact,
* it controls timing for both master and slave drives.
*/
drive_enables |= 0x4000;
if (is_slave) { if (is_slave) {
master_data |= 0x4000; drive_enables &= 0xc006;
if (pio > 1) if (pio > 1)
/* enable PPE and IE */ /* enable prefetch and IORDY sample-point */
master_data |= 0x0060; drive_enables |= 0x0060;
} else { } else {
master_data &= 0xc060; drive_enables &= 0xc060;
if (pio > 1) if (pio > 1)
/* enable PPE and IE */ /* enable prefetch and IORDY sample-point */
master_data |= 0x0006; drive_enables |= 0x0006;
} }
save_flags(flags); save_flags(flags);
...@@ -163,6 +169,7 @@ static int it8172_tune_chipset (ide_drive_t *drive, byte speed) ...@@ -163,6 +169,7 @@ static int it8172_tune_chipset (ide_drive_t *drive, byte speed)
case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break;
case XFER_MW_DMA_2: case XFER_MW_DMA_2:
case XFER_MW_DMA_1: case XFER_MW_DMA_1:
case XFER_MW_DMA_0:
case XFER_SW_DMA_2: break; case XFER_SW_DMA_2: break;
default: return -1; default: return -1;
} }
...@@ -185,7 +192,7 @@ static int it8172_tune_chipset (ide_drive_t *drive, byte speed) ...@@ -185,7 +192,7 @@ static int it8172_tune_chipset (ide_drive_t *drive, byte speed)
return err; return err;
} }
static int it8172_config_drive_for_dma(ide_drive_t *drive) static int it8172_config_chipset_for_dma(ide_drive_t *drive)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
byte speed; byte speed;
...@@ -205,7 +212,7 @@ static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive) ...@@ -205,7 +212,7 @@ static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
{ {
switch (func) { switch (func) {
case ide_dma_check: case ide_dma_check:
return ide_dmaproc((ide_dma_action_t)it8172_config_drive_for_dma(drive), return ide_dmaproc((ide_dma_action_t)it8172_config_chipset_for_dma(drive),
drive); drive);
default : default :
break; break;
......
/* -*- linux-c -*- /* -*- linux-c -*-
* linux/drivers/ide/pdc4030.c Version 0.90 May 27, 1999 * linux/drivers/ide/pdc4030.c Version 0.92 Jan 15, 2002
* *
* Copyright (C) 1995-1999 Linus Torvalds & authors (see below) * Copyright (C) 1995-2002 Linus Torvalds & authors (see below)
*/ */
/* /*
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
* Autodetection code added. * Autodetection code added.
* *
* Version 0.90 Transition to BETA code. No lost/unexpected interrupts * Version 0.90 Transition to BETA code. No lost/unexpected interrupts
* Version 0.91 Bring in line with new bio code in 2.5.1
* Version 0.92 Update for IDE driver taskfile changes
*/ */
/* /*
...@@ -72,8 +74,8 @@ ...@@ -72,8 +74,8 @@
* effects. * effects.
*/ */
#define DEBUG_READ #undef DEBUG_READ
#define DEBUG_WRITE #undef DEBUG_WRITE
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -91,6 +93,10 @@ ...@@ -91,6 +93,10 @@
#include "pdc4030.h" #include "pdc4030.h"
#if SUPPORT_VLB_SYNC != 1
#error This driver will not work unless SUPPORT_VLB_SYNC is 1
#endif
/* /*
* promise_selectproc() is invoked by ide.c * promise_selectproc() is invoked by ide.c
* in preparation for access to the specified drive. * in preparation for access to the specified drive.
...@@ -229,12 +235,12 @@ int __init setup_pdc4030(struct ata_channel *hwif) ...@@ -229,12 +235,12 @@ int __init setup_pdc4030(struct ata_channel *hwif)
hwif->selectproc = hwif2->selectproc = &promise_selectproc; hwif->selectproc = hwif2->selectproc = &promise_selectproc;
hwif->serialized = hwif2->serialized = 1; hwif->serialized = hwif2->serialized = 1;
/* Shift the remaining interfaces down by one */ /* Shift the remaining interfaces up by one */
for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) { for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) {
struct ata_channel *h = &ide_hwifs[i]; struct ata_channel *h = &ide_hwifs[i];
#ifdef DEBUG #ifdef DEBUG
printk(KERN_DEBUG "Shifting i/f %d values to i/f %d\n",i-1,i); printk(KERN_DEBUG "pdc4030: Shifting i/f %d values to i/f %d\n",i-1,i);
#endif #endif
ide_init_hwif_ports(&h->hw, (h-1)->io_ports[IDE_DATA_OFFSET], 0, NULL); ide_init_hwif_ports(&h->hw, (h-1)->io_ports[IDE_DATA_OFFSET], 0, NULL);
memcpy(h->io_ports, h->hw.io_ports, sizeof(h->io_ports)); memcpy(h->io_ports, h->hw.io_ports, sizeof(h->io_ports));
...@@ -652,8 +658,8 @@ ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigne ...@@ -652,8 +658,8 @@ ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigne
are distinguished by writing the drive number (0-3) to the are distinguished by writing the drive number (0-3) to the
Feature register. Feature register.
FIXME: Is promise_selectproc now redundant?? FIXME: Is promise_selectproc now redundant??
*/ */
taskfile.feature = (drive->channel->unit << 1) + drive->select.b.unit; taskfile.feature = (drive->channel->unit << 1) + drive->select.b.unit;
taskfile.sector_count = rq->nr_sectors; taskfile.sector_count = rq->nr_sectors;
taskfile.sector_number = block; taskfile.sector_number = block;
taskfile.low_cylinder = (block>>=8); taskfile.low_cylinder = (block>>=8);
......
...@@ -975,6 +975,7 @@ extern void revalidate_drives(void); ...@@ -975,6 +975,7 @@ extern void revalidate_drives(void);
#define ATA_AR_QUEUED 1 #define ATA_AR_QUEUED 1
#define ATA_AR_SETUP 2 #define ATA_AR_SETUP 2
#define ATA_AR_RETURN 4 #define ATA_AR_RETURN 4
#define ATA_AR_STATIC 8
/* /*
* if turn-around time is longer than this, halve queue depth * if turn-around time is longer than this, halve queue depth
...@@ -1015,7 +1016,8 @@ static inline struct ata_request *ata_ar_get(ide_drive_t *drive) ...@@ -1015,7 +1016,8 @@ static inline struct ata_request *ata_ar_get(ide_drive_t *drive)
static inline void ata_ar_put(ide_drive_t *drive, struct ata_request *ar) static inline void ata_ar_put(ide_drive_t *drive, struct ata_request *ar)
{ {
list_add(&ar->ar_queue, &drive->free_req); if (!(ar->ar_flags & ATA_AR_STATIC))
list_add(&ar->ar_queue, &drive->free_req);
if (ar->ar_flags & ATA_AR_QUEUED) { if (ar->ar_flags & ATA_AR_QUEUED) {
/* clear the tag */ /* clear the tag */
......
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