From: Jens Axboe <axboe@suse.de>
To: Martin Knoblauch <martin.knoblauch@mscsoftware.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: Oops + Aiee when mounting CDROM via ide-scsi under 2.4.20-pre5-ac4
Date: Tue, 10 Sep 2002 21:13:24 +0200 [thread overview]
Message-ID: <20020910191324.GJ21877@suse.de> (raw)
In-Reply-To: <20020910190906.GI21877@suse.de>
On Tue, Sep 10 2002, Jens Axboe wrote:
> On Tue, Sep 10 2002, Martin Knoblauch wrote:
> > Hi,
> >
> > I am getting a reproducable Oops+Aiee when trying to mount a ATAPI
> > CDROM via the ide-scsi interface under 2.4.20-pre5-ac4. Works OK
> > without ide-scsi.
>
> Ok, the problem is that ide-scsi builds a request which eventually ends
> up going through the ide code dma mapping. ide_build_sglist() does a
> rq_data_dir() on the request, which BUG()'s if the command isn't an fs
> read or write. This actually went undetected before, because the ide
> code did:
>
> if (rq->cmd == READ)
> direction is dma from device
> else
> direction is to device
>
> and rq->cmd is IDESCSI_PC_RQ in this case. So we always mapped for dma
> to the device, even if that wasn't the case.
>
> Hmm, maybe just adding a single direction bit to struct request is the
> easy way out for 2.4. Or... I'll cook something up.
ok try this patch, against 2.4.20-pre5-ac4 (well not a clean one, but I
think it should apply).
alan, this should probably go into ac5 provided that Martin tests it as
ok.
diff -ur -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.20-pre5-ac4/drivers/ide/arm/icside.c linux-2.4.20-pre5-ac4/drivers/ide/arm/icside.c
--- /opt/kernel/linux-2.4.20-pre5-ac4/drivers/ide/arm/icside.c 2002-09-10 12:56:51.000000000 +0200
+++ linux-2.4.20-pre5-ac4/drivers/ide/arm/icside.c 2002-09-10 21:04:58.000000000 +0200
@@ -264,9 +264,9 @@
}
static int
-icside_build_dmatable(ide_drive_t *drive, int reading)
+icside_build_dmatable(ide_drive_t *drive, int ddir)
{
- return HWIF(drive)->sg_nents = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
+ return HWIF(drive)->sg_nents = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq, ddir);
}
/* Teardown mappings after DMA has completed. */
@@ -556,7 +556,7 @@
u8 lba48 = (drive->addressing == 1) ? 1 : 0;
task_ioreg_t command = WIN_NOP;
- count = icside_build_dmatable(drive, 1);
+ count = icside_build_dmatable(drive, PCI_DMA_FROMDEVICE);
if (!count)
return 1;
disable_dma(hwif->hw.dma);
@@ -610,7 +610,7 @@
u8 lba48 = (drive->addressing == 1) ? 1 : 0;
task_ioreg_t command = WIN_NOP;
- count = icside_build_dmatable(drive, 0);
+ count = icside_build_dmatable(drive, PCI_DMA_TODEVICE);
if (!count)
return 1;
disable_dma(hwif->hw.dma);
diff -ur -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.20-pre5-ac4/drivers/ide/ide-dma.c linux-2.4.20-pre5-ac4/drivers/ide/ide-dma.c
--- /opt/kernel/linux-2.4.20-pre5-ac4/drivers/ide/ide-dma.c 2002-09-10 12:56:51.000000000 +0200
+++ linux-2.4.20-pre5-ac4/drivers/ide/ide-dma.c 2002-09-10 21:03:11.000000000 +0200
@@ -215,7 +214,7 @@
return DRIVER(drive)->error(drive, "dma_intr", stat);
}
-static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq)
+static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq, int ddir)
{
struct buffer_head *bh;
struct scatterlist *sg = hwif->sg_table;
@@ -223,11 +222,7 @@
if (hwif->sg_dma_active)
BUG();
-
- if (rq_data_dir(rq) == READ)
- hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
- else
- hwif->sg_dma_direction = PCI_DMA_TODEVICE;
+
bh = rq->bh;
do {
unsigned char *virt_addr = bh->b_data;
@@ -252,7 +247,8 @@
if(nents == 0)
BUG();
- return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
+ hwif->sg_dma_direction = ddir;
+ return pci_map_sg(hwif->pci_dev, sg, nents, ddir);
}
static int ide_raw_build_sglist (ide_hwif_t *hwif, struct request *rq)
@@ -302,7 +298,7 @@
* Returns 0 if all went okay, returns 1 otherwise.
* May also be invoked from trm290.c
*/
-int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
+int ide_build_dmatable (ide_drive_t *drive, struct request *rq, int ddir)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned int *table = hwif->dmatable_cpu;
@@ -314,7 +310,7 @@
if (rq->cmd == IDE_DRIVE_TASKFILE)
hwif->sg_nents = i = ide_raw_build_sglist(hwif, rq);
else
- hwif->sg_nents = i = ide_build_sglist(hwif, rq);
+ hwif->sg_nents = i = ide_build_sglist(hwif, rq, ddir);
if (!i)
return 0;
@@ -543,7 +539,7 @@
u8 dma_stat = 0, lba48 = (drive->addressing == 1) ? 1 : 0;
task_ioreg_t command = WIN_NOP;
- if (!(count = ide_build_dmatable(drive, rq)))
+ if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_FROMDEVICE)))
/* try PIO instead of DMA */
return 1;
/* PRD table */
@@ -595,7 +591,7 @@
u8 dma_stat = 0, lba48 = (drive->addressing == 1) ? 1 : 0;
task_ioreg_t command = WIN_NOP;
- if (!(count = ide_build_dmatable(drive, rq)))
+ if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_TODEVICE)))
/* try PIO instead of DMA */
return 1;
/* PRD table */
diff -ur -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.20-pre5-ac4/drivers/ide/pci/trm290.c linux-2.4.20-pre5-ac4/drivers/ide/pci/trm290.c
--- /opt/kernel/linux-2.4.20-pre5-ac4/drivers/ide/pci/trm290.c 2002-09-10 12:56:52.000000000 +0200
+++ linux-2.4.20-pre5-ac4/drivers/ide/pci/trm290.c 2002-09-10 21:08:15.000000000 +0200
@@ -191,7 +191,7 @@
trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
#endif
- if (!(count = ide_build_dmatable(drive, rq))) {
+ if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_TODEVICE))) {
/* try PIO instead of DMA */
trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
@@ -235,7 +235,7 @@
task_ioreg_t command = WIN_NOP;
unsigned int count, reading = 2, writing = 0;
- if (!(count = ide_build_dmatable(drive, rq))) {
+ if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_FROMDEVICE))) {
/* try PIO instead of DMA */
trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
diff -ur -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.20-pre5-ac4/drivers/ide/ppc/pmac.c linux-2.4.20-pre5-ac4/drivers/ide/ppc/pmac.c
--- /opt/kernel/linux-2.4.20-pre5-ac4/drivers/ide/ppc/pmac.c 2002-09-10 12:56:52.000000000 +0200
+++ linux-2.4.20-pre5-ac4/drivers/ide/ppc/pmac.c 2002-09-10 21:07:42.000000000 +0200
@@ -932,7 +932,7 @@
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
static int
-pmac_ide_build_sglist(ide_hwif_t *hwif, struct request *rq)
+pmac_ide_build_sglist(ide_hwif_t *hwif, struct request *rq, int data_dir)
{
pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
struct buffer_head *bh;
@@ -942,10 +942,6 @@
if (hwif->sg_dma_active)
BUG();
- if (rq->cmd == READ)
- pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
- else
- pmif->sg_dma_direction = PCI_DMA_TODEVICE;
bh = rq->bh;
do {
unsigned char *virt_addr = bh->b_data;
@@ -965,7 +961,8 @@
nents++;
} while (bh != NULL);
- return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction);
+ pmif->sg_dma_direction = data_dir;
+ return pci_map_sg(hwif->pci_dev, sg, nents, data_dir);
}
static int
@@ -1013,6 +1010,7 @@
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
volatile struct dbdma_regs *dma = pmif->dma_regs;
struct scatterlist *sg;
+ int data_dir;
/* DMA table is already aligned */
table = (struct dbdma_cmd *) pmif->dma_table_cpu;
@@ -1022,11 +1020,16 @@
while (readl(&dma->status) & RUN)
udelay(1);
+ if (wr)
+ data_dir = PCI_DMA_TODEVICE;
+ else
+ data_dir = PCI_DMA_FROMDEVICE;
+
/* Build sglist */
if (rq->cmd == IDE_DRIVE_TASKFILE)
pmif->sg_nents = i = pmac_ide_raw_build_sglist(hwif, rq);
else
- pmif->sg_nents = i = pmac_ide_build_sglist(hwif, rq);
+ pmif->sg_nents = i = pmac_ide_build_sglist(hwif, rq, data_dir);
if (!i)
return 0;
diff -ur -X /home/axboe/cdrom/exclude /opt/kernel/linux-2.4.20-pre5-ac4/include/linux/ide.h linux-2.4.20-pre5-ac4/include/linux/ide.h
--- /opt/kernel/linux-2.4.20-pre5-ac4/include/linux/ide.h 2002-09-10 12:56:54.000000000 +0200
+++ linux-2.4.20-pre5-ac4/include/linux/ide.h 2002-09-10 21:04:00.000000000 +0200
@@ -1732,7 +1732,7 @@
#ifdef CONFIG_BLK_DEV_IDEDMA
#define BAD_DMA_DRIVE 0
#define GOOD_DMA_DRIVE 1
-extern int ide_build_dmatable(ide_drive_t *, struct request *);
+extern int ide_build_dmatable(ide_drive_t *, struct request *, int);
extern void ide_destroy_dmatable(ide_drive_t *);
extern ide_startstop_t ide_dma_intr(ide_drive_t *);
extern int ide_release_dma(ide_hwif_t *);
--
Jens Axboe
next prev parent reply other threads:[~2002-09-10 19:09 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-09-10 18:15 Oops + Aiee when mounting CDROM via ide-scsi under 2.4.20-pre5-ac4 Martin Knoblauch
2002-09-10 19:09 ` Jens Axboe
2002-09-10 19:13 ` Jens Axboe [this message]
-- strict thread matches above, loose matches on Subject: below --
2002-09-11 10:28 Martin Knoblauch
2002-09-11 10:34 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020910191324.GJ21877@suse.de \
--to=axboe@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.knoblauch@mscsoftware.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.