lkml.org 
[lkml]   [2002]   [Jan]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: Linux 2.5.3-pre1-aia1 (fwd)

Failed to attached the patch.


Andre Hedrick
Linux Disk Certification Project Linux ATA Development

---------- Forwarded message ----------
Date: Mon, 21 Jan 2002 01:48:10 -0800 (PST)
From: Andre Hedrick <andre@linuxdiskcert.org>
To: Jens Axboe <axboe@suse.de>
Cc: Davide Libenzi <davidel@xmailserver.org>,
Anton Altaparmakov <aia21@cam.ac.uk>,
Linus Torvalds <torvalds@transmeta.com>,
lkml <linux-kernel@vger.kernel.org>
Subject: Re: Linux 2.5.3-pre1-aia1

On Mon, 21 Jan 2002, Jens Axboe wrote:

> On Mon, Jan 21 2002, Andre Hedrick wrote:
> > > This really sucks, it means we cannot safely use multi mode for a
> > > variety of request sizes. I agree with your earlier comment. Here's what
> > > I think we should be doing: when requesting multi mode, limit to 8
> > > sectors like in your patch. This is by far the most commen multiple,
> > > that's why. When starting a request, use WIN_MULT* only for cases where
> > > (rq->nr_sectors % drive->mult_count) == 0. If that doesn't hold, simply
> > > use WIN_READ or WIN_WRITE.
> > >
> > > Applied the 2.5.3-pre2 sched SMP fix, booting -pre2 and then hacking up
> > > a patch.
> >
> > Why I have already done it, just take and apply.
>
> Cool, where is it?

Attached, and please do not pick and choose.

I moved and added things for a reason as not to loose hard work, because
of writing the ISR's to the purity of the spec, and then we modify ISR's
to fit the kernel and not the other way around. I do have a just reason
to request a MEMPOOL, which would be exclusively used for PIO operations.
Then we get out of the mess we are in and get in to serious compliance to
how the hardware works.

Thus in the offline comments about the creation of an ata_request_struct,
a mempool allocation for PIO is justified. Since the correct solution of
DMA timeouts is to void the request and assume no data down is valid.
Thus PIO is next.

If we look at the overhead in the generation of a new request for each and
every time we do a PIO transfer it is scary. Think about this issue for
more than the time it takes to hit the delete key.

Respectfully,

Andre Hedrick
Linux Disk Certification Project Linux ATA Development

diff -urN linux-2.5.3-p2-pristine/drivers/ide/cmd64x.c linux-2.5.3-p2/drivers/ide/cmd64x.c
--- linux-2.5.3-p2-pristine/drivers/ide/cmd64x.c Sun Jan 20 00:25:44 2002
+++ linux-2.5.3-p2/drivers/ide/cmd64x.c Sun Jan 20 01:00:55 2002
@@ -538,6 +538,11 @@
if ((speed == XFER_UDMA_6) && (scsc & 0x30) == 0x00) {
pci_write_config_byte(dev, 0x8A, scsc|0x01);
pci_read_config_byte(dev, 0x8A, &scsc);
+#if 0
+ /* if 133 clock fails, switch to 2xbus clock */
+ if (!(scsc & 0x01))
+ pci_write_config_byte(dev, 0x8A, scsc|0x10);
+#endif
}

switch(speed) {
@@ -975,6 +980,13 @@
pci_write_config_byte(dev, 0x84, 0x00);
pci_read_config_byte(dev, 0x8A, &tmpbyte);
pci_write_config_byte(dev, 0x8A, tmpbyte|0x01);
+#if 0
+ /* if 133 clock fails, switch to 2xbus clock */
+ if (!(tmpbyte & 0x01)) {
+ pci_read_config_byte(dev, 0x8A, &tmpbyte);
+ pci_write_config_byte(dev, 0x8A, tmpbyte|0x10);
+ }
+#endif
pci_write_config_word(dev, 0xA2, 0x328A);
pci_write_config_dword(dev, 0xA4, 0x328A);
pci_write_config_dword(dev, 0xA8, 0x4392);
diff -urN linux-2.5.3-p2-pristine/drivers/ide/hpt34x.c linux-2.5.3-p2/drivers/ide/hpt34x.c
--- linux-2.5.3-p2-pristine/drivers/ide/hpt34x.c Tue Nov 27 09:23:27 2001
+++ linux-2.5.3-p2/drivers/ide/hpt34x.c Sun Jan 20 00:40:11 2002
@@ -335,9 +335,28 @@
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
return 0;
- ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
- OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
- return 0;
+ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
+ /* issue cmd to drive */
+ /*
+ * FIX ME to use only ACB ide_task_t args Struct
+ */
+#if 0
+ {
+ ide_task_t *args = HWGROUP(drive)->rq->special;
+ OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+ }
+#else
+ if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
+ (drive->addressing == 1)) {
+ ide_task_t *args = HWGROUP(drive)->rq->special;
+ OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+ } else if (drive->addressing) {
+ OUT_BYTE((reading == 9) ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+ } else {
+ OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+ }
+#endif
+ return HWIF(drive)->dmaproc(ide_dma_begin, drive);
case ide_dma_end: /* returns 1 on error, 0 otherwise */
drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */
diff -urN linux-2.5.3-p2-pristine/drivers/ide/icside.c linux-2.5.3-p2/drivers/ide/icside.c
--- linux-2.5.3-p2-pristine/drivers/ide/icside.c Tue Dec 25 21:43:32 2001
+++ linux-2.5.3-p2/drivers/ide/icside.c Sun Jan 20 00:40:11 2002
@@ -547,9 +547,25 @@
return 0;

ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL);
- OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
- IDE_COMMAND_REG);
-
+ /*
+ * FIX ME to use only ACB ide_task_t args Struct
+ */
+#if 0
+ {
+ ide_task_t *args = HWGROUP(drive)->rq->special;
+ OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG); }
+#else
+ if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
+ (drive->addressing == 1)) {
+ ide_task_t *args = HWGROUP(drive)->rq->special;
+ OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+ } else if (drive->addressing) {
+ OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+ } else {
+ OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+ }
+#endif
+ return HWIF(drive)->dmaproc(ide_dma_begin, drive);
case ide_dma_begin:
enable_dma(hwif->hw.dma);
return 0;
diff -urN linux-2.5.3-p2-pristine/drivers/ide/ide-disk.c linux-2.5.3-p2/drivers/ide/ide-disk.c
--- linux-2.5.3-p2-pristine/drivers/ide/ide-disk.c Sun Jan 20 00:25:44 2002
+++ linux-2.5.3-p2/drivers/ide/ide-disk.c Mon Jan 21 00:01:20 2002
@@ -177,7 +177,7 @@
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
ide_task_t args;
- int sectors;
+ int sectors = rq->nr_sectors;

task_ioreg_t command = get_command(drive, rq_data_dir(rq));

@@ -189,13 +189,14 @@
memset(&taskfile, 0, sizeof(task_struct_t));
memset(&hobfile, 0, sizeof(hob_struct_t));

- sectors = rq->nr_sectors;
if (sectors == 256)
sectors = 0;
- if (command == WIN_MULTWRITE_EXT || command == WIN_MULTWRITE) {
+ if (command == WIN_MULTWRITE) {
sectors = drive->mult_count;
if (sectors > rq->current_nr_sectors)
sectors = rq->current_nr_sectors;
+ if (sectors != drive->mult_count)
+ command = WIN_WRITE;
}

taskfile.sector_count = sectors;
@@ -234,17 +235,18 @@
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
ide_task_t args;
- int sectors;
+ int sectors = rq->nr_sectors;

task_ioreg_t command = get_command(drive, rq_data_dir(rq));

- sectors = rq->nr_sectors;
if (sectors == 256)
sectors = 0;
- if (command == WIN_MULTWRITE_EXT || command == WIN_MULTWRITE) {
+ if (command == WIN_MULTWRITE) {
sectors = drive->mult_count;
if (sectors > rq->current_nr_sectors)
sectors = rq->current_nr_sectors;
+ if (sectors != drive->mult_count)
+ command = WIN_WRITE;
}

memset(&taskfile, 0, sizeof(task_struct_t));
@@ -292,30 +294,26 @@
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
ide_task_t args;
- int sectors;
+ int sectors = rq->nr_sectors;

task_ioreg_t command = get_command(drive, rq_data_dir(rq));

memset(&taskfile, 0, sizeof(task_struct_t));
memset(&hobfile, 0, sizeof(hob_struct_t));

- sectors = rq->nr_sectors;
- if (sectors == 256)
+ if (sectors == 65536)
sectors = 0;
- if (command == WIN_MULTWRITE_EXT || command == WIN_MULTWRITE) {
+
+ if (command == WIN_MULTWRITE_EXT) {
sectors = drive->mult_count;
if (sectors > rq->current_nr_sectors)
sectors = rq->current_nr_sectors;
+ if (sectors != drive->mult_count)
+ command = WIN_WRITE_EXT;
}

taskfile.sector_count = sectors;
hobfile.sector_count = sectors >> 8;
-
- if (rq->nr_sectors == 65536) {
- taskfile.sector_count = 0x00;
- hobfile.sector_count = 0x00;
- }
-
taskfile.sector_number = block; /* low lba */
taskfile.low_cylinder = (block>>=8); /* mid lba */
taskfile.high_cylinder = (block>>=8); /* hi lba */
@@ -674,6 +672,8 @@
s->b.set_multmode = 0;
if (drive->id && drive->mult_req > drive->id->max_multsect)
drive->mult_req = drive->id->max_multsect;
+ if (drive->mult_req > 8)
+ drive->mult_req = 8;
if (!IS_PDC4030_DRIVE) {
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
@@ -1040,6 +1040,8 @@
drive->special.b.set_multmode = 1;
#endif /* CONFIG_IDEDISK_MULTI_MODE */
}
+ if (drive->mult_req > 8)
+ drive->mult_req = 8;
drive->no_io_32bit = id->dword_io ? 1 : 0;
if (drive->id->cfs_enable_2 & 0x3000)
write_cache(drive, (id->cfs_enable_2 & 0x3000));
diff -urN linux-2.5.3-p2-pristine/drivers/ide/ide-dma.c linux-2.5.3-p2/drivers/ide/ide-dma.c
--- linux-2.5.3-p2-pristine/drivers/ide/ide-dma.c Sun Jan 20 00:25:44 2002
+++ linux-2.5.3-p2/drivers/ide/ide-dma.c Sun Jan 20 00:40:11 2002
@@ -606,18 +606,38 @@
case ide_dma_write:
SELECT_READ_WRITE(hwif,drive,func);
if (!(count = ide_build_dmatable(drive, func)))
- return 1; /* try PIO instead of DMA */
- outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
- outb(reading, dma_base); /* specify r/w */
- outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
+ /*
+ * try PIO instead of DMA !!!FIXME
+ *
+ * Mark the request for PIO and end_request to be queued.
+ * Noting the future TIMEOUT model do the same less
+ * device reset, needed to recover drive to command mode.
+ */
+ return 1;
+ /* PRD table */
+ outl(hwif->dmatable_dma, dma_base + 4);
+ /* specify r/w */
+ outb(reading, dma_base);
+ /* clear INTR & ERROR flags */
+ outb(inb(dma_base+2)|6, dma_base+2);
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
return 0;
#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
- ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL); /* issue cmd to drive */
+ ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL);
#else /* !CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
- ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */
+ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry);
#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
+ /* issue cmd to drive */
+ /*
+ * FIX ME to use only ACB ide_task_t args Struct
+ */
+#if 0
+ {
+ ide_task_t *args = HWGROUP(drive)->rq->special;
+ OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+ }
+#else
if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
(drive->addressing == 1)) {
ide_task_t *args = HWGROUP(drive)->rq->special;
@@ -627,6 +647,7 @@
} else {
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
}
+#endif
return HWIF(drive)->dmaproc(ide_dma_begin, drive);
case ide_dma_begin:
/* Note that this is done *after* the cmd has
@@ -634,15 +655,21 @@
* The Promise Ultra33 doesn't work correctly when
* we do this part before issuing the drive cmd.
*/
- outb(inb(dma_base)|1, dma_base); /* start DMA */
+ /* start DMA */
+ outb(inb(dma_base)|1, dma_base);
return 0;
case ide_dma_end: /* returns 1 on error, 0 otherwise */
drive->waiting_for_dma = 0;
- outb(inb(dma_base)&~1, dma_base); /* stop DMA */
- dma_stat = inb(dma_base+2); /* get DMA status */
- outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
- ide_destroy_dmatable(drive); /* purge DMA mappings */
- return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */
+ /* stop DMA */
+ outb(inb(dma_base)&~1, dma_base);
+ /* get DMA status */
+ dma_stat = inb(dma_base+2);
+ /* clear the INTR & ERROR bits */
+ outb(dma_stat|6, dma_base+2);
+ /* purge DMA mappings */
+ ide_destroy_dmatable(drive);
+ /* verify good DMA status */
+ return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
dma_stat = inb(dma_base+2);
#if 0 /* do not set unless you know what you are doing */
@@ -651,21 +678,22 @@
outb(dma_base+2, dma_stat & 0xE4);
}
#endif
- return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
+ /* return 1 if INTR asserted */
+ return (dma_stat & 4) == 4;
case ide_dma_bad_drive:
case ide_dma_good_drive:
return check_drive_lists(drive, (func == ide_dma_good_drive));
case ide_dma_verbose:
return report_drive_dmaing(drive);
case ide_dma_timeout:
- // FIXME: Many IDE chipsets do not permit command file register access
- // FIXME: while the bus-master function is still active.
- // FIXME: To prevent deadlock with those chipsets, we must be extremely
- // FIXME: careful here (and in ide_intr() as well) to NOT access any
- // FIXME: registers from the 0x1Fx/0x17x sets before terminating the
- // FIXME: bus-master operation via the bus-master control reg.
- // FIXME: Otherwise, chipset deadlock will occur, and some systems will
- // FIXME: lock up completely!!
+ // FIXME: Many IDE chipsets do not permit command file register access
+ // FIXME: while the bus-master function is still active.
+ // FIXME: To prevent deadlock with those chipsets, we must be extremely
+ // FIXME: careful here (and in ide_intr() as well) to NOT access any
+ // FIXME: registers from the 0x1Fx/0x17x sets before terminating the
+ // FIXME: bus-master operation via the bus-master control reg.
+ // FIXME: Otherwise, chipset deadlock will occur, and some systems will
+ // FIXME: lock up completely!!
#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
/*
* Have to issue an abort and requeue the request
diff -urN linux-2.5.3-p2-pristine/drivers/ide/ide-pmac.c linux-2.5.3-p2/drivers/ide/ide-pmac.c
--- linux-2.5.3-p2-pristine/drivers/ide/ide-pmac.c Sun Jan 20 00:25:44 2002
+++ linux-2.5.3-p2/drivers/ide/ide-pmac.c Sun Jan 20 00:40:11 2002
@@ -215,32 +215,6 @@
#define SYSCLK_TICKS(t) (((t) + IDE_SYSCLK_NS - 1) / IDE_SYSCLK_NS)
#define SYSCLK_TICKS_UDMA(t) (((t) + IDE_SYSCLK_ULTRA_PS - 1) / IDE_SYSCLK_ULTRA_PS)

-static __inline__ int
-wait_for_ready(ide_drive_t *drive)
-{
- /* Timeout bumped for some powerbooks */
- int timeout = 2000;
- byte stat;
-
- while(--timeout) {
- stat = GET_STAT();
- if(!(stat & BUSY_STAT)) {
- if (drive->ready_stat == 0)
- break;
- else if((stat & drive->ready_stat) || (stat & ERR_STAT))
- break;
- }
- mdelay(1);
- }
- if((stat & ERR_STAT) || timeout <= 0) {
- if (stat & ERR_STAT) {
- printk(KERN_ERR "ide_pmac: wait_for_ready, error status: %x\n", stat);
- }
- return 1;
- }
- return 0;
-}
-
/* Note: We don't use the generic routine here because some of Apple's
* controller seem to be very sensitive about how things are done.
* We should probably set the NIEN bit, but that's an example of thing
@@ -261,7 +235,8 @@
SELECT_DRIVE(HWIF(drive), drive);
SELECT_MASK(HWIF(drive), drive, 0);
udelay(1);
- if(wait_for_ready(drive)) {
+ /* Timeout bumped for some powerbooks */
+ if(wait_for_ready(drive, 2000)) {
printk(KERN_ERR "pmac_ide_do_setfeature disk not ready before SET_FEATURE!\n");
goto out;
}
@@ -269,7 +244,8 @@
OUT_BYTE(command, IDE_NSECTOR_REG);
OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
udelay(1);
- result = wait_for_ready(drive);
+ /* Timeout bumped for some powerbooks */
+ result = wait_for_ready(drive, 2000);
if (result)
printk(KERN_ERR "pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n");
out:
@@ -988,8 +964,27 @@
if (drive->media != ide_disk)
return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
- OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
- IDE_COMMAND_REG);
+ /* issue cmd to drive */
+ /*
+ * FIX ME to use only ACB ide_task_t args Struct
+ */
+#if 0
+ {
+ ide_task_t *args = HWGROUP(drive)->rq->special;
+ OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+ }
+#else
+ if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
+ (drive->addressing == 1)) {
+ ide_task_t *args = HWGROUP(drive)->rq->special;
+ OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+ } else if (drive->addressing) {
+ OUT_BYTE((func==ide_dma_write) ? WIN_WRITEDMA_EXT : WIN_READDMA_EXT, IDE_COMMAND_REG);
+ } else {
+ OUT_BYTE((func==ide_dma_write) ? WIN_WRITEDMA : WIN_READDMA, IDE_COMMAND_REG);
+ }
+#endif
+// return HWIF(drive)->dmaproc(ide_dma_begin, drive);
case ide_dma_begin:
out_le32(&dma->control, (RUN << 16) | RUN);
break;
diff -urN linux-2.5.3-p2-pristine/drivers/ide/ide-taskfile.c linux-2.5.3-p2/drivers/ide/ide-taskfile.c
--- linux-2.5.3-p2-pristine/drivers/ide/ide-taskfile.c Sun Jan 20 00:25:44 2002
+++ linux-2.5.3-p2/drivers/ide/ide-taskfile.c Sun Jan 20 00:40:11 2002
@@ -1,8 +1,11 @@
/*
- * linux/drivers/ide/ide-taskfile.c Version 0.20 Oct 11, 2000
+ * linux/drivers/ide/ide-taskfile.c Version 0.25 Jan 17, 2001
*
- * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
- * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
+ * Copyright (C) 2000-2002 Michael Cornwell <cornwell@acm.org>
+ * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
+ *
+ * BIO Glue Layer into 2.5.3-pre1,pre2
+ * Jens Axboe <axboe@brick.kernel.dk>
*
* May be copied or modified under the terms of the GNU General Public License
*
@@ -42,6 +45,33 @@
#define DTF(x...)
#endif

+/*
+ *
+ */
+#define task_rq_offset(rq) \
+ (((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE)
+
+/*
+ * for now, taskfile requests are special :/
+ *
+ * However, upon the creation of the atapi version of packet_command
+ * data-phase ISR plus it own diagnostics and extensions for direct access
+ * (ioctl,read,write,rip,stream -- atapi), the kmap/kunmap for PIO will
+ * come localized.
+ */
+inline char *task_map_rq (struct request *rq, unsigned long *flags)
+{
+ if (rq->bio)
+ return ide_map_buffer(rq, flags);
+ return rq->buffer + task_rq_offset(rq);
+}
+
+inline void task_unmap_rq (struct request *rq, char *buf, unsigned long *flags)
+{
+ if (rq->bio)
+ ide_unmap_buffer(buf, flags);
+}
+
inline u32 task_read_24 (ide_drive_t *drive)
{
return (IN_BYTE(IDE_HCYL_REG)<<16) |
@@ -255,6 +285,32 @@
return 1; /* drive ready: *might* be interrupting */
}

+/*
+ * Global for All, and taken from ide-pmac.c
+ */
+int wait_for_ready (ide_drive_t *drive, int timeout)
+{
+ byte stat = 0;
+
+ while(--timeout) {
+ stat = GET_STAT();
+ if(!(stat & BUSY_STAT)) {
+ if (drive->ready_stat == 0)
+ break;
+ else if((stat & drive->ready_stat) || (stat & ERR_STAT))
+ break;
+ }
+ mdelay(1);
+ }
+ if((stat & ERR_STAT) || timeout <= 0) {
+ if (stat & ERR_STAT) {
+ printk(KERN_ERR "%s: wait_for_ready, error status: %x\n", drive->name, stat);
+ }
+ return 1;
+ }
+ return 0;
+}
+
ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
{
task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
@@ -736,21 +792,25 @@
}
}
DTF("stat: %02x\n", stat);
- pBuf = ide_map_rq(rq, &flags);
+ pBuf = task_map_rq(rq, &flags);
DTF("Read: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);

drive->io_32bit = 0;
taskfile_input_data(drive, pBuf, SECTOR_WORDS);
- ide_unmap_rq(rq, pBuf, &flags);
+ task_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;

if (--rq->current_nr_sectors <= 0) {
/* (hs): swapped next 2 lines */
DTF("Request Ended stat: %02x\n", GET_STAT());
+#if 0 /* original data-phase */
+ ide_end_request(1, HWGROUP(drive));
+#else
if (ide_end_request(1, HWGROUP(drive))) {
ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
return ide_started;
}
+#endif
} else {
ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
return ide_started;
@@ -821,7 +881,7 @@
return ide_error(drive, "task_mulin_intr", stat);
}
/* no data yet, so wait for another interrupt */
- ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
+ ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL);
return ide_started;
}

@@ -840,11 +900,11 @@
*/
nsect = 1;
while (rq->current_nr_sectors) {
- pBuf = ide_map_rq(rq, &flags);
+ pBuf = task_map_rq(rq, &flags);
DTF("Multiread: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
- ide_unmap_rq(rq, pBuf, &flags);
+ task_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
@@ -855,18 +915,36 @@
}
#endif /* ALTSTAT_SCREW_UP */

+#if 0 /* original data-phase */
+ nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors;
+ pBuf = task_map_rq(rq, &flags);
+ DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
+ pBuf, nsect, rq->current_nr_sectors);
+ drive->io_32bit = 0;
+ taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
+ task_unmap_rq(rq, pBuf, &flags);
+ drive->io_32bit = io_32bit;
+ rq->errors = 0;
+ rq->current_nr_sectors -= nsect;
+ if (rq->current_nr_sectors != 0) {
+ ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL);
+ return ide_started;
+ }
+ ide_end_request(1, HWGROUP(drive));
+ return ide_stopped;
+#else
do {
nsect = rq->current_nr_sectors;
if (nsect > msect)
nsect = msect;

- pBuf = ide_map_rq(rq, &flags);
+ pBuf = task_map_rq(rq, &flags);

DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
- ide_unmap_rq(rq, pBuf, &flags);
+ task_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
@@ -877,12 +955,12 @@
}
} while (msect);

-
/*
* more data left
*/
- ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
+ ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL);
return ide_started;
+#endif
}

ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
@@ -899,11 +977,11 @@
if ((args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE) &&
(args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE_EXT)) {
unsigned long flags;
- char *buf = ide_map_rq(rq, &flags);
+ char *pBuf = task_map_rq(rq, &flags);
/* For Write_sectors we need to stuff the first sector */
- taskfile_output_data(drive, buf, SECTOR_WORDS);
+ taskfile_output_data(drive, pBuf, SECTOR_WORDS);
rq->current_nr_sectors--;
- ide_unmap_rq(rq, buf, &flags);
+ task_unmap_rq(rq, pBuf, &flags);
} else {
/*
* (ks/hs): Stuff the first sector(s)
@@ -948,21 +1026,25 @@

if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) {
rq = HWGROUP(drive)->rq;
- pBuf = ide_map_rq(rq, &flags);
+ pBuf = task_map_rq(rq, &flags);
DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_output_data(drive, pBuf, SECTOR_WORDS);
- ide_unmap_rq(rq, pBuf, &flags);
+ task_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors--;
}

if (rq->current_nr_sectors <= 0) {
+#if 0 /* original data-phase */
+ ide_end_request(1, HWGROUP(drive));
+#else
if (ide_end_request(1, HWGROUP(drive))) {
ide_set_handler(drive, &task_out_intr, WAIT_CMD, NULL);
return ide_started;
}
+#endif
} else {
ide_set_handler(drive, &task_out_intr, WAIT_CMD, NULL);
return ide_started;
@@ -998,7 +1080,6 @@
if (rq->current_nr_sectors == 0) {
if (stat & (ERR_STAT|DRQ_STAT))
return ide_error(drive, "task_mulout_intr", stat);
-
/*
* there may be more, ide_do_request will restart it if
* necessary
@@ -1028,11 +1109,11 @@
if (!msect) {
nsect = 1;
while (rq->current_nr_sectors) {
- pBuf = ide_map_rq(rq, &flags);
+ pBuf = task_map_rq(rq, &flags);
DTF("Multiwrite: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
- ide_unmap_rq(pBuf, &flags);
+ task_unmap_rq(pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
@@ -1043,16 +1124,19 @@
}
#endif /* ALTSTAT_SCREW_UP */

+#if 0 /* original data-phase */
+ nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors;
+#else
nsect = rq->current_nr_sectors;
if (nsect > msect)
nsect = msect;
-
- pBuf = ide_map_rq(rq, &flags);
+#endif
+ pBuf = task_map_rq(rq, &flags);
DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
- ide_unmap_rq(rq, pBuf, &flags);
+ task_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
rq->current_nr_sectors -= nsect;
@@ -1364,6 +1448,7 @@
args.command_type = ide_cmd_type_parser (&args);
if (args.command_type != IDE_DRIVE_TASK_NO_DATA)
rq.current_nr_sectors = rq.nr_sectors = (hobfile->sector_count << 8) | taskfile->sector_count;
+ /* rq.hard_cur_sectors */

rq.buffer = buf;
rq.special = &args;
@@ -1378,6 +1463,7 @@

if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
rq.current_nr_sectors = rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET_HOB] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET];
+ /* rq.hard_cur_sectors */

rq.special = args;
return ide_do_drive_cmd(drive, &rq, ide_wait);
@@ -1689,6 +1775,7 @@
}

EXPORT_SYMBOL(drive_is_ready);
+EXPORT_SYMBOL(wait_for_ready);
EXPORT_SYMBOL(task_read_24);
EXPORT_SYMBOL(ata_input_data);
EXPORT_SYMBOL(ata_output_data);
diff -urN linux-2.5.3-p2-pristine/drivers/ide/pdc202xx.c linux-2.5.3-p2/drivers/ide/pdc202xx.c
--- linux-2.5.3-p2-pristine/drivers/ide/pdc202xx.c Sun Jan 20 00:25:44 2002
+++ linux-2.5.3-p2/drivers/ide/pdc202xx.c Sun Jan 20 00:40:11 2002
@@ -900,7 +900,7 @@
return ide_dma_off_quietly;
}

- outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+ OUT_BYTE(IN_BYTE(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
(void) hwif->speedproc(drive, speed);

return ((int) ((id->dma_ultra >> 14) & 3) ? ide_dma_on :
@@ -1086,7 +1086,7 @@
#if 0
ide_hwif_t *hwif = HWIF(drive);
unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4);
- byte sc1f = inb(high_16 + 0x001f);
+ byte sc1f = IN_BYTE(high_16 + 0x001f);

if (!hwif)
return -EINVAL;
@@ -1094,9 +1094,9 @@
// hwif->bus_state = state;

if (state) {
- outb(sc1f | 0x08, high_16 + 0x001f);
+ OUT_BYTE(sc1f | 0x08, high_16 + 0x001f);
} else {
- outb(sc1f & ~0x08, high_16 + 0x001f);
+ OUT_BYTE(sc1f & ~0x08, high_16 + 0x001f);
}
#endif
return 0;
diff -urN linux-2.5.3-p2-pristine/drivers/ide/pdc4030.c linux-2.5.3-p2/drivers/ide/pdc4030.c
--- linux-2.5.3-p2-pristine/drivers/ide/pdc4030.c Sun Jan 20 00:25:44 2002
+++ linux-2.5.3-p2/drivers/ide/pdc4030.c Sun Jan 20 00:40:11 2002
@@ -554,6 +554,13 @@
unsigned long timeout;
byte stat;

+/* Check that it's a regular command. If not, bomb out early. */
+ if (!(rq->flags & REQ_CMD)) {
+ blk_dump_rq_flags(rq, "pdc4030 bad flags");
+ ide_end_request(0, HWGROUP(drive));
+ return ide_stopped;
+ }
+
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
SELECT_MASK(HWIF(drive), drive, 0);
@@ -568,16 +575,8 @@
OUT_BYTE(taskfile->device_head, IDE_SELECT_REG);
OUT_BYTE(taskfile->command, IDE_COMMAND_REG);

-/* Check that it's a regular command. If not, bomb out early. */
- if (!(rq->flags & REQ_CMD)) {
- blk_dump_rq_flags(rq, "pdc4030 bad flags");
- ide_end_request(0, HWGROUP(drive));
- return ide_stopped;
- }
-
switch (rq_data_dir(rq)) {
case READ:
- OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
/*
* The card's behaviour is odd at this point. If the data is
* available, DRQ will be true, and no interrupt will be
@@ -611,8 +610,6 @@
return ide_stopped;

case WRITE: {
- ide_startstop_t startstop;
- OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
/*
* Strategy on write is:
* look for the DRQ that should have been immediately asserted
diff -urN linux-2.5.3-p2-pristine/drivers/ide/serverworks.c linux-2.5.3-p2/drivers/ide/serverworks.c
--- linux-2.5.3-p2-pristine/drivers/ide/serverworks.c Sun Jan 20 00:25:44 2002
+++ linux-2.5.3-p2/drivers/ide/serverworks.c Sun Jan 20 00:40:11 2002
@@ -349,9 +349,9 @@
pci_write_config_byte(dev, 0x54, ultra_enable);

if (speed > XFER_PIO_4)
- outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
+ OUT_BYTE(IN_BYTE(dma_base+2)|(1<<(5+unit)), dma_base+2);
else
- outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+ OUT_BYTE(IN_BYTE(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
#endif /* CONFIG_BLK_DEV_IDEDMA */

err = ide_config_drive_speed(drive, speed);
diff -urN linux-2.5.3-p2-pristine/drivers/ide/sis5513.c linux-2.5.3-p2/drivers/ide/sis5513.c
--- linux-2.5.3-p2-pristine/drivers/ide/sis5513.c Tue Nov 27 09:23:27 2001
+++ linux-2.5.3-p2/drivers/ide/sis5513.c Sun Jan 20 00:46:51 2002
@@ -37,8 +37,11 @@
#define SIS5513_FLAG_ATA_16 0x00000001
#define SIS5513_FLAG_ATA_33 0x00000002
#define SIS5513_FLAG_ATA_66 0x00000004
+#define SIS5513_FLAG_ATA_100 0x00000008
#define SIS5513_FLAG_LATENCY 0x00000010

+static unsigned int capabilities = 0x00000000;
+
static const struct {
const char *name;
unsigned short host_id;
@@ -48,15 +51,15 @@
{ "SiS540", PCI_DEVICE_ID_SI_540, SIS5513_FLAG_ATA_66, },
{ "SiS620", PCI_DEVICE_ID_SI_620, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
{ "SiS630", PCI_DEVICE_ID_SI_630, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
- { "SiS635", PCI_DEVICE_ID_SI_635, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+ { "SiS635", PCI_DEVICE_ID_SI_635, SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
{ "SiS640", PCI_DEVICE_ID_SI_640, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
- { "SiS645", PCI_DEVICE_ID_SI_645, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
- { "SiS650", PCI_DEVICE_ID_SI_650, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
- { "SiS730", PCI_DEVICE_ID_SI_730, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
- { "SiS735", PCI_DEVICE_ID_SI_735, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
- { "SiS740", PCI_DEVICE_ID_SI_740, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
- { "SiS745", PCI_DEVICE_ID_SI_745, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
- { "SiS750", PCI_DEVICE_ID_SI_750, SIS5513_FLAG_ATA_66|SIS5513_FLAG_LATENCY, },
+ { "SiS645", PCI_DEVICE_ID_SI_645, SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+ { "SiS650", PCI_DEVICE_ID_SI_650, SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+ { "SiS730", PCI_DEVICE_ID_SI_730, SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+ { "SiS735", PCI_DEVICE_ID_SI_735, SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+ { "SiS740", PCI_DEVICE_ID_SI_740, SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+ { "SiS745", PCI_DEVICE_ID_SI_745, SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
+ { "SiS750", PCI_DEVICE_ID_SI_750, SIS5513_FLAG_ATA_100|SIS5513_FLAG_LATENCY, },
{ "SiS5591", PCI_DEVICE_ID_SI_5591, SIS5513_FLAG_ATA_33, },
{ "SiS5597", PCI_DEVICE_ID_SI_5597, SIS5513_FLAG_ATA_33, },
{ "SiS5600", PCI_DEVICE_ID_SI_5600, SIS5513_FLAG_ATA_33, },
@@ -148,6 +151,17 @@
"6 PCICLK", "12 PCICLK"
};

+static char* cycle_time_ata100[] = {
+ "Reserved", "2 CLK",
+ "3 CLK", "4 CLK",
+ "5 CLK", "6 CLK",
+ "7 CLK", "8 CLK",
+ "9 CLK", "10 CLK",
+ "11 CLK", "12 CLK",
+ "Reserved", "Reserved",
+ "Reserved", "Reserved"
+};
+
static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
{
int rc;
@@ -189,11 +203,19 @@
p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n",
(reg & 0x80) ? "Enabled" : "Disabled",
(reg1 & 0x80) ? "Enabled" : "Disabled");
- p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
- cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
- p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
- active_time[(reg & 0x07)], active_time[(reg1 &0x07)] );
-
+ if (capabilities && SIS5513_FLAG_ATA_100) {
+ p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
+ cycle_time_ata100[reg & 0x0F], cycle_time_ata100[reg1 & 0x0F]);
+ rc = pci_read_config_byte(bmide_dev, 0x40, &reg);
+ rc = pci_read_config_byte(bmide_dev, 0x44, &reg1);
+ p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
+ active_time[(reg & 0x70) >> 4], active_time[(reg1 & 0x70) >> 4]);
+ } else {
+ p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
+ cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
+ p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
+ active_time[(reg & 0x07)], active_time[(reg1 &0x07)] );
+ }
rc = pci_read_config_byte(bmide_dev, 0x40, &reg);
rc = pci_read_config_byte(bmide_dev, 0x44, &reg1);
p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n",
@@ -213,10 +235,19 @@
p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n",
(reg & 0x80) ? "Enabled" : "Disabled",
(reg1 & 0x80) ? "Enabled" : "Disabled");
- p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
- cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
- p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
- active_time[(reg & 0x07)], active_time[(reg1 &0x07)] );
+ if (capabilities && SIS5513_FLAG_ATA_100) {
+ p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
+ cycle_time_ata100[reg & 0x0F], cycle_time_ata100[reg1 & 0x0F]);
+ rc = pci_read_config_byte(bmide_dev, 0x42, &reg);
+ rc = pci_read_config_byte(bmide_dev, 0x46, &reg1);
+ p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
+ active_time[(reg & 0x70) >> 4], active_time[(reg1 & 0x70) >> 4]);
+ } else {
+ p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
+ cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
+ p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
+ active_time[(reg & 0x07)], active_time[(reg1 &0x07)] );
+ }

rc = pci_read_config_byte(bmide_dev, 0x42, &reg);
rc = pci_read_config_byte(bmide_dev, 0x46, &reg1);
@@ -229,6 +260,7 @@
byte sis_proc = 0;
extern char *ide_xfer_verbose (byte xfer_rate);

+/* Enables Prefetch and Postwrite on drive */
static void config_drive_art_rwp (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -243,8 +275,10 @@

if ((reg4bh & rw_prefetch) != rw_prefetch)
pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
+ printk("SIS5513: config_drive_art_rwp, drive %d\n", drive->dn);
}

+/* Set active and recovery time */
static void config_art_rwp_pio (ide_drive_t *drive, byte pio)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -274,6 +308,8 @@

timing = (xfer_pio >= pio) ? xfer_pio : pio;

+ printk("SIS5513: config_drive_art_rwp_pio, drive %d, pio %d, timing %d\n",
+ drive->dn, pio, timing);
/*
* Mode 0 Mode 1 Mode 2 Mode 3 Mode 4
* Active time 8T (240ns) 6T (180ns) 4T (120ns) 3T (90ns) 3T (90ns)
@@ -291,6 +327,19 @@
default: return;
}

+ if (capabilities && SIS5513_FLAG_ATA_100) {
+ switch(timing) { /* active recovery
+ v v */
+ case 4: test1 = 0x30|0x01; break;
+ case 3: test1 = 0x30|0x03; break;
+ case 2: test1 = 0x40|0x04; break;
+ case 1: test1 = 0x60|0x07; break;
+ default: break;
+ }
+ pci_write_config_byte(dev, drive_pci, test1);
+ return; /* temporary hack for tests */
+ }
+
pci_read_config_byte(dev, drive_pci, &test1);
pci_read_config_byte(dev, drive_pci|0x01, &test2);

@@ -298,8 +347,8 @@
* Do a blanket clear of active and recovery timings.
*/

- test1 &= ~0x07;
- test2 &= ~0x0F;
+ test1 &= ~0x0F;
+ test2 &= ~0x07;

switch(timing) {
case 4: test1 |= 0x01; test2 |= 0x03; break;
@@ -340,6 +389,9 @@
byte drive_pci, test1, test2;
byte unmask, four_two, mask = 0;

+ printk("SIS5513: sis5513_tune_chipset, drive %d, speed %d\n",
+ drive->dn, speed);
+
if (host_dev) {
switch(host_dev->device) {
case PCI_DEVICE_ID_SI_530:
@@ -379,6 +431,7 @@
pci_read_config_byte(dev, drive_pci, &test1);
pci_read_config_byte(dev, drive_pci|0x01, &test2);

+ /* If not an UDMA mode switch off udma bit */
if ((speed <= XFER_MW_DMA_2) && (test2 & 0x80)) {
pci_write_config_byte(dev, drive_pci|0x01, test2 & ~0x80);
pci_read_config_byte(dev, drive_pci|0x01, &test2);
@@ -386,7 +439,31 @@
pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);
}

- switch(speed) {
+ if (capabilities & SIS5513_FLAG_ATA_100) {
+ switch(speed) {
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ case XFER_UDMA_5: mask = 0x01; break;
+ case XFER_UDMA_4: mask = 0x02; break;
+ case XFER_UDMA_3: mask = 0x04; break;
+ case XFER_UDMA_2: mask = 0x05; break;
+ case XFER_UDMA_1: mask = 0x07; break;
+ case XFER_UDMA_0: mask = 0x0B; break;
+ case XFER_MW_DMA_2:
+ case XFER_MW_DMA_1:
+ case XFER_MW_DMA_0:
+ case XFER_SW_DMA_2:
+ case XFER_SW_DMA_1:
+ case XFER_SW_DMA_0: break;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+ case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));
+ case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));
+ case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));
+ case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
+ case XFER_PIO_0:
+ default: return((int) config_chipset_for_pio(drive, 0));
+ }
+ } else {
+ switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_UDMA_5: mask = 0x80; break;
case XFER_UDMA_4: mask = 0x90; break;
@@ -407,10 +484,16 @@
case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));
case XFER_PIO_0:
default: return((int) config_chipset_for_pio(drive, 0));
+ }
}

- if (speed > XFER_MW_DMA_2)
- pci_write_config_byte(dev, drive_pci|0x01, test2|mask);
+ if (speed > XFER_MW_DMA_2) {
+ if (capabilities & SIS5513_FLAG_ATA_100) {
+ pci_write_config_byte(dev, drive_pci|0x01, 0x80|mask);
+ } else {
+ pci_write_config_byte(dev, drive_pci|0x01, test2|mask);
+ }
+ }

drive->current_speed = speed;
return ((int) ide_config_drive_speed(drive, speed));
@@ -437,6 +520,9 @@
byte udma_66 = eighty_ninty_three(drive);
byte ultra_100 = 0;

+ printk("SIS5513: config_chipset_for_dma, drive %d, ultra %d\n",
+ drive->dn, ultra);
+
if (host_dev) {
switch(host_dev->device) {
case PCI_DEVICE_ID_SI_635:
@@ -487,7 +573,7 @@
else
return ((int) ide_dma_off_quietly);

- outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
+ OUT_BYTE(IN_BYTE(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);

err = sis5513_tune_chipset(drive, speed);

@@ -583,6 +669,7 @@
continue;

host_dev = host;
+ capabilities = SiSHostChipInfo[i].flags;
printk(SiSHostChipInfo[i].name);
printk("\n");
if (SiSHostChipInfo[i].flags & SIS5513_FLAG_LATENCY) {
@@ -592,12 +679,22 @@
}

if (host_dev) {
- byte reg52h = 0;
+ if (capabilities & SIS5513_FLAG_ATA_100) {
+ byte reg49h = 0;

- pci_read_config_byte(dev, 0x52, &reg52h);
- if (!(reg52h & 0x04)) {
- /* set IDE controller to operate in Compabitility mode only */
- pci_write_config_byte(dev, 0x52, reg52h|0x04);
+ pci_read_config_byte(dev, 0x49, &reg49h);
+ if (!(reg49h & 0x01)) {
+ /* set IDE controller to operate in Compabitility mode only */
+ pci_write_config_byte(dev, 0x49, reg49h|0x01);
+ }
+ } else {
+ byte reg52h = 0;
+
+ pci_read_config_byte(dev, 0x52, &reg52h);
+ if (!(reg52h & 0x04)) {
+ /* set IDE controller to operate in Compabitility mode only */
+ pci_write_config_byte(dev, 0x52, reg52h|0x04);
+ }
}
#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
if (!sis_proc) {
diff -urN linux-2.5.3-p2-pristine/drivers/ide/trm290.c linux-2.5.3-p2/drivers/ide/trm290.c
--- linux-2.5.3-p2-pristine/drivers/ide/trm290.c Tue Jun 20 07:52:36 2000
+++ linux-2.5.3-p2/drivers/ide/trm290.c Sun Jan 20 00:40:11 2002
@@ -195,8 +195,26 @@
if (drive->media != ide_disk)
return 0;
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
- OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
- return 0;
+/*
+ * FIX ME to use only ACB ide_task_t args Struct
+ */
+#if 0
+ {
+ ide_task_t *args = HWGROUP(drive)->rq->special;
+ OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+ }
+#else
+ if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
+ (drive->addressing == 1)) {
+ ide_task_t *args = HWGROUP(drive)->rq->special;
+ OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+ } else if (drive->addressing) {
+ OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+ } else {
+ OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+ }
+#endif
+ return HWIF(drive)->dmaproc(ide_dma_begin, drive);
case ide_dma_begin:
return 0;
case ide_dma_end:
diff -urN linux-2.5.3-p2-pristine/include/linux/ide.h linux-2.5.3-p2/include/linux/ide.h
--- linux-2.5.3-p2-pristine/include/linux/ide.h Sun Jan 20 00:25:59 2002
+++ linux-2.5.3-p2/include/linux/ide.h Sun Jan 20 00:40:11 2002
@@ -329,9 +329,11 @@
#ifdef REALLY_FAST_IO
#define OUT_BYTE(b,p) outb((b),(p))
#define OUT_WORD(w,p) outw((w),(p))
+#define OUT_LONG(l,p) outl((l),(p))
#else
#define OUT_BYTE(b,p) outb_p((b),(p))
#define OUT_WORD(w,p) outw_p((w),(p))
+#define OUT_LONG(l,p) outl_p((l),(p))
#endif
#endif

@@ -339,9 +341,11 @@
#ifdef REALLY_FAST_IO
#define IN_BYTE(p) (byte)inb(p)
#define IN_WORD(p) (short)inw(p)
+#define IN_LONG(p) (int)inl(p)
#else
#define IN_BYTE(p) (byte)inb_p(p)
#define IN_WORD(p) (short)inw_p(p)
+#define IN_LONG(p) (int)inl_p(p)
#endif
#endif

@@ -786,8 +790,6 @@
inline int __ide_end_request(ide_hwgroup_t *, int, int);
int ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup);

-int drive_is_ready (ide_drive_t *drive);
-
/*
* This is used on exit from the driver, to designate the next irq handler
* and also to start the safety timer.
@@ -882,10 +884,8 @@
/*
* temporarily mapping a (possible) highmem bio for PIO transfer
*/
-#define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
-
-#define task_rq_offset(rq) \
- (((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE)
+#define ide_rq_offset(rq) \
+ (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)

extern inline void *ide_map_buffer(struct request *rq, unsigned long *flags)
{
@@ -898,24 +898,6 @@
}

/*
- * for now, taskfile requests are special :/
- */
-extern inline char *ide_map_rq(struct request *rq, unsigned long *flags)
-{
- if (rq->bio)
- return ide_map_buffer(rq, flags);
- else
- return rq->buffer + task_rq_offset(rq);
-}
-
-extern inline void ide_unmap_rq(struct request *rq, char *buf,
- unsigned long *flags)
-{
- if (rq->bio)
- ide_unmap_buffer(buf, flags);
-}
-
-/*
* This function issues a special IDE device request
* onto the request queue.
*
@@ -971,12 +953,25 @@
unsigned long block; /* copy of block */
} ide_task_t;

+typedef struct pkt_task_s {
+ task_ioreg_t tfRegister[8];
+ int data_phase;
+ int command_type;
+ ide_handler_t *handler;
+ void *special;
+ struct request *rq; /* copy of request */
+ unsigned long block; /* copy of block */
+} pkt_task_t;
+
void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
+
+int drive_is_ready (ide_drive_t *drive);
+int wait_for_ready (ide_drive_t *drive, int timeout);

/*
* taskfile io for disks for now...
\
 
 \ /
  Last update: 2005-03-22 13:15    [W:0.054 / U:0.488 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site