From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
To: torvalds@osdl.org
Cc: linux-ide@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [BK PATCHES] ide-2.6 update
Date: Fri, 22 Oct 2004 19:38:44 +0200 [thread overview]
Message-ID: <58cb370e04102210385ca8b554@mail.gmail.com> (raw)
More syncing with -mm.
Please do a
bk pull bk://bart.bkbits.net/ide-2.6
This will update the following files:
arch/cris/arch-v10/drivers/ide.c | 10 -
drivers/ide/arm/icside.c | 38 +----
drivers/ide/ide-cd.c | 5
drivers/ide/ide-disk.c | 2
drivers/ide/ide-dma.c | 87 ++-----------
drivers/ide/ide-io.c | 12 +
drivers/ide/ide-proc.c | 257 ---------------------------------------
drivers/ide/ide.c | 1
drivers/ide/pci/sgiioc4.c | 17 --
drivers/ide/pci/siimage.c | 7 -
drivers/ide/ppc/pmac.c | 58 --------
drivers/scsi/ide-scsi.c | 141 +++++++--------------
include/linux/ide.h | 6
13 files changed, 95 insertions(+), 546 deletions(-)
through these ChangeSets:
<bzolnier@trik.(none)> (04/10/22 1.2055)
[ide] kill /proc/ide/ide?/config
* writes to PCI config space are non-functional since 2.4.21
* reads of full PCI config space are allowed for normal users
* I'm not aware of any applications using this interface
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
<bzolnier@trik.(none)> (04/10/22 1.2054)
[ide] kill ide_hwif_t->ide_dma_verbose
* make __ide_dma_verbose() void and drop "__" prefix
* ide_dma_verbose() is always available now
* use it instead of ide_hwif_t->ide_dma_verbose
* sgiioc4.c version reported wrong mode
* icside.c version repeated info given by ->ide_dma_check()
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
<bzolnier@trik.(none)> (04/10/22 1.2053)
[ide] ide-scsi: simplify+speedup DMA support
* add hwif->sg_mapped flag
* add idescsi_map_sg() converting scsi_cmd->sg into
hwif->sg_table (this removes need for rq->bio)
* remove code (de)allocating rq->bio
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
<bzolnier@trik.(none)> (04/10/22 1.2052)
[ide] kill ide_raw_build_sglist()
ide_build_sglist() can be now used for REQ_DRIVE_TASKFILE requests.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
<bzolnier@trik.(none)> (04/10/22 1.2051)
[ide] use ide_map_sg()
* make Etrax ide.c, icside.c and ide-dma.c use ide_map_sg()
* use one sg for REQ_DRIVE_TASKFILE requests in ide-dma.c
(no reason for 128 sectors per sg limit)
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
<bzolnier@trik.(none)> (04/10/22 1.2050)
[ide] pmac: kill pmac_ide_[raw_]build_sglist()
Just use ide_dma_[raw_]build_sglist() from ide-dma.c.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
diff -Nru a/arch/cris/arch-v10/drivers/ide.c b/arch/cris/arch-v10/drivers/ide.c
--- a/arch/cris/arch-v10/drivers/ide.c 2004-10-22 19:29:05 +02:00
+++ b/arch/cris/arch-v10/drivers/ide.c 2004-10-22 19:29:05 +02:00
@@ -656,15 +656,9 @@
ata_tot_size = 0;
- if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
- sg_init_one(&sg[0], rq->buffer, rq->nr_sectors * SECTOR_SIZE);
- hwif->sg_nents = i = 1;
- }
- else
- {
- hwif->sg_nents = i = blk_rq_map_sg(drive->queue, rq, hwif->sg_table);
- }
+ ide_map_sg(drive, rq);
+ i = hwif->sg_nents;
while(i) {
/*
diff -Nru a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
--- a/drivers/ide/arm/icside.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/arm/icside.c 2004-10-22 19:29:05 +02:00
@@ -212,33 +212,18 @@
ide_hwif_t *hwif = drive->hwif;
struct icside_state *state = hwif->hwif_data;
struct scatterlist *sg = hwif->sg_table;
- int nents;
- if (rq->flags & REQ_DRIVE_TASKFILE) {
- ide_task_t *args = rq->special;
+ ide_map_sg(drive, rq);
- if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
- hwif->sg_dma_direction = DMA_TO_DEVICE;
- else
- hwif->sg_dma_direction = DMA_FROM_DEVICE;
-
- sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
- nents = 1;
- } else {
- nents = blk_rq_map_sg(drive->queue, rq, sg);
-
- if (rq_data_dir(rq) == READ)
- hwif->sg_dma_direction = DMA_FROM_DEVICE;
- else
- hwif->sg_dma_direction = DMA_TO_DEVICE;
- }
-
- nents = dma_map_sg(state->dev, sg, nents, hwif->sg_dma_direction);
+ if (rq_data_dir(rq) == READ)
+ hwif->sg_dma_direction = DMA_FROM_DEVICE;
+ else
+ hwif->sg_dma_direction = DMA_TO_DEVICE;
- hwif->sg_nents = nents;
+ hwif->sg_nents = dma_map_sg(state->dev, sg, hwif->sg_nents,
+ hwif->sg_dma_direction);
}
-
/*
* Configure the IOMD to give the appropriate timings for the transfer
* mode being requested. We take the advice of the ATA standards, and
@@ -498,14 +483,6 @@
ICS_ARCIN_V6_INTRSTAT_1)) & 1;
}
-static int icside_dma_verbose(ide_drive_t *drive)
-{
- printk(", %s (peak %dMB/s)",
- ide_xfer_verbose(drive->current_speed),
- 2000 / drive->drive_data);
- return 1;
-}
-
static int icside_dma_timeout(ide_drive_t *drive)
{
printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
@@ -554,7 +531,6 @@
hwif->dma_start = icside_dma_start;
hwif->ide_dma_end = icside_dma_end;
hwif->ide_dma_test_irq = icside_dma_test_irq;
- hwif->ide_dma_verbose = icside_dma_verbose;
hwif->ide_dma_timeout = icside_dma_timeout;
hwif->ide_dma_lostirq = icside_dma_lostirq;
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/ide-cd.c 2004-10-22 19:29:05 +02:00
@@ -3039,10 +3039,9 @@
printk(", %dkB Cache", be16_to_cpu(cap.buffer_size));
-#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->using_dma)
- (void) HWIF(drive)->ide_dma_verbose(drive);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+ ide_dma_verbose(drive);
+
printk("\n");
return nslots;
diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
--- a/drivers/ide/ide-disk.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/ide-disk.c 2004-10-22 19:29:05 +02:00
@@ -1244,7 +1244,7 @@
printk(", CHS=%d/%d/%d",
drive->bios_cyl, drive->bios_head, drive->bios_sect);
if (drive->using_dma)
- (void) HWIF(drive)->ide_dma_verbose(drive);
+ ide_dma_verbose(drive);
printk("\n");
drive->mult_count = 0;
diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
--- a/drivers/ide/ide-dma.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/ide-dma.c 2004-10-22 19:29:05 +02:00
@@ -207,67 +207,23 @@
{
ide_hwif_t *hwif = HWIF(drive);
struct scatterlist *sg = hwif->sg_table;
- int nents;
- nents = blk_rq_map_sg(drive->queue, rq, hwif->sg_table);
-
+ if ((rq->flags & REQ_DRIVE_TASKFILE) && rq->nr_sectors > 256)
+ BUG();
+
+ ide_map_sg(drive, rq);
+
if (rq_data_dir(rq) == READ)
hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
else
hwif->sg_dma_direction = PCI_DMA_TODEVICE;
- return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
+ return pci_map_sg(hwif->pci_dev, sg, hwif->sg_nents, hwif->sg_dma_direction);
}
EXPORT_SYMBOL_GPL(ide_build_sglist);
/**
- * ide_raw_build_sglist - map IDE scatter gather for DMA
- * @drive: the drive to build the DMA table for
- * @rq: the request holding the sg list
- *
- * Perform the PCI mapping magic necessary to access the source or
- * target buffers of a taskfile request via PCI DMA. The lower layers
- * of the kernel provide the necessary cache management so that we can
- * operate in a portable fashion
- */
-
-int ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
-{
- ide_hwif_t *hwif = HWIF(drive);
- struct scatterlist *sg = hwif->sg_table;
- int nents = 0;
- ide_task_t *args = rq->special;
- u8 *virt_addr = rq->buffer;
- int sector_count = rq->nr_sectors;
-
- if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
- hwif->sg_dma_direction = PCI_DMA_TODEVICE;
- else
- hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-
-#if 1
- if (sector_count > 256)
- BUG();
-
- if (sector_count > 128) {
-#else
- while (sector_count > 128) {
-#endif
- sg_init_one(&sg[nents], virt_addr, 128 * SECTOR_SIZE);
- nents++;
- virt_addr = virt_addr + (128 * SECTOR_SIZE);
- sector_count -= 128;
- }
- sg_init_one(&sg[nents], virt_addr, sector_count * SECTOR_SIZE);
- nents++;
-
- return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
-}
-
-EXPORT_SYMBOL_GPL(ide_raw_build_sglist);
-
-/**
* ide_build_dmatable - build IDE DMA table
*
* ide_build_dmatable() prepares a dma request. We map the command
@@ -288,10 +244,7 @@
int i;
struct scatterlist *sg;
- if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
- hwif->sg_nents = i = ide_raw_build_sglist(drive, rq);
- else
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
+ hwif->sg_nents = i = ide_build_sglist(drive, rq);
if (!i)
return 0;
@@ -728,17 +681,14 @@
EXPORT_SYMBOL(__ide_dma_good_drive);
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
-int __ide_dma_verbose (ide_drive_t *drive)
+void ide_dma_verbose(ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = HWIF(drive);
if (id->field_valid & 4) {
- if ((id->dma_ultra >> 8) && (id->dma_mword >> 8)) {
- printk(", BUG DMA OFF");
- return hwif->ide_dma_off_quietly(drive);
- }
+ if ((id->dma_ultra >> 8) && (id->dma_mword >> 8))
+ goto bug_dma_off;
if (id->dma_ultra & ((id->dma_ultra >> 8) & hwif->ultra_mask)) {
if (((id->dma_ultra >> 11) & 0x1F) &&
eighty_ninty_three(drive)) {
@@ -768,19 +718,22 @@
printk(", (U)DMA"); /* Can be BIOS-enabled! */
}
} else if (id->field_valid & 2) {
- if ((id->dma_mword >> 8) && (id->dma_1word >> 8)) {
- printk(", BUG DMA OFF");
- return hwif->ide_dma_off_quietly(drive);
- }
+ if ((id->dma_mword >> 8) && (id->dma_1word >> 8))
+ goto bug_dma_off;
printk(", DMA");
} else if (id->field_valid & 1) {
printk(", BUG");
}
- return 1;
+ return;
+bug_dma_off:
+ printk(", BUG DMA OFF");
+ hwif->ide_dma_off_quietly(drive);
+ return;
}
-EXPORT_SYMBOL(__ide_dma_verbose);
+EXPORT_SYMBOL(ide_dma_verbose);
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
int __ide_dma_lostirq (ide_drive_t *drive)
{
printk("%s: DMA interrupt recovery\n", drive->name);
@@ -955,8 +908,6 @@
hwif->ide_dma_end = &__ide_dma_end;
if (!hwif->ide_dma_test_irq)
hwif->ide_dma_test_irq = &__ide_dma_test_irq;
- if (!hwif->ide_dma_verbose)
- hwif->ide_dma_verbose = &__ide_dma_verbose;
if (!hwif->ide_dma_timeout)
hwif->ide_dma_timeout = &__ide_dma_timeout;
if (!hwif->ide_dma_lostirq)
diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
--- a/drivers/ide/ide-io.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/ide-io.c 2004-10-22 19:29:05 +02:00
@@ -680,6 +680,9 @@
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
+ if (hwif->sg_mapped) /* needed by ide-scsi */
+ return;
+
if ((rq->flags & REQ_DRIVE_TASKFILE) == 0) {
hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
} else {
@@ -1219,12 +1222,15 @@
HWGROUP(drive)->rq = NULL;
rq->errors = 0;
+
+ if (!rq->bio)
+ goto out;
+
rq->sector = rq->bio->bi_sector;
rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
rq->hard_cur_sectors = rq->current_nr_sectors;
- if (rq->bio)
- rq->buffer = NULL;
-
+ rq->buffer = NULL;
+out:
return ret;
}
diff -Nru a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
--- a/drivers/ide/ide-proc.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/ide-proc.c 2004-10-22 19:29:05 +02:00
@@ -8,37 +8,6 @@
/*
* This is the /proc/ide/ filesystem implementation.
*
- * The major reason this exists is to provide sufficient access
- * to driver and config data, such that user-mode programs can
- * be developed to handle chipset tuning for most PCI interfaces.
- * This should provide better utilities, and less kernel bloat.
- *
- * The entire pci config space for a PCI interface chipset can be
- * retrieved by just reading it. e.g. "cat /proc/ide3/config"
- *
- * To modify registers *safely*, do something like:
- * echo "P40:88" >/proc/ide/ide3/config
- * That expression writes 0x88 to pci config register 0x40
- * on the chip which controls ide3. Multiple tuples can be issued,
- * and the writes will be completed as an atomic set:
- * echo "P40:88 P41:35 P42:00 P43:00" >/proc/ide/ide3/config
- *
- * All numbers must be specified using pairs of ascii hex digits.
- * It is important to note that these writes will be performed
- * after waiting for the IDE controller (both interfaces)
- * to be completely idle, to ensure no corruption of I/O in progress.
- *
- * Non-PCI registers can also be written, using "R" in place of "P"
- * in the above examples. The size of the port transfer is determined
- * by the number of pairs of hex digits given for the data. If a two
- * digit value is given, the write will be a byte operation; if four
- * digits are used, the write will be performed as a 16-bit operation;
- * and if eight digits are specified, a 32-bit "dword" write will be
- * performed. Odd numbers of digits are not permitted.
- *
- * If there is an error *anywhere* in the string of registers/data
- * then *none* of the writes will be performed.
- *
* Drive/Driver settings can be retrieved by reading the drive's
* "settings" files. e.g. "cat /proc/ide0/hda/settings"
* To write a new value "val" into a specific setting "name", use:
@@ -51,10 +20,6 @@
* returned data as 256 16-bit words. The "hdparm" utility will
* be updated someday soon to use this mechanism.
*
- * Feel free to develop and distribute fancy GUI configuration
- * utilities for your favorite PCI chipsets. I'll be working on
- * one for the Promise 20246 someday soon. -ml
- *
*/
#include <linux/config.h>
@@ -74,227 +39,6 @@
#include <asm/io.h>
-static int proc_ide_write_config(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
-{
- ide_hwif_t *hwif = (ide_hwif_t *)data;
- ide_hwgroup_t *mygroup = (ide_hwgroup_t *)(hwif->hwgroup);
- ide_hwgroup_t *mategroup = NULL;
- unsigned long timeout;
- unsigned long flags;
- const char *start = NULL, *msg = NULL;
- struct entry { u32 val; u16 reg; u8 size; u8 pci; } *prog, *q, *r;
- int want_pci = 0;
- char *buf, *s;
- int err;
-
- if (hwif->mate && hwif->mate->hwgroup)
- mategroup = (ide_hwgroup_t *)(hwif->mate->hwgroup);
-
- if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
- return -EACCES;
-
- if (count >= PAGE_SIZE)
- return -EINVAL;
-
- s = buf = (char *)__get_free_page(GFP_USER);
- if (!buf)
- return -ENOMEM;
-
- err = -ENOMEM;
- q = prog = (struct entry *)__get_free_page(GFP_USER);
- if (!prog)
- goto out;
-
- err = -EFAULT;
- if (copy_from_user(buf, buffer, count))
- goto out1;
-
- buf[count] = '\0';
-
- while (isspace(*s))
- s++;
-
- while (*s) {
- char *p;
- int digits;
-
- start = s;
-
- if ((char *)(q + 1) > (char *)prog + PAGE_SIZE) {
- msg = "too many entries";
- goto parse_error;
- }
-
- switch (*s++) {
- case 'R': q->pci = 0;
- break;
- case 'P': q->pci = 1;
- want_pci = 1;
- break;
- default: msg = "expected 'R' or 'P'";
- goto parse_error;
- }
-
- q->reg = simple_strtoul(s, &p, 16);
- digits = p - s;
- if (!digits || digits > 4 || (q->pci && q->reg > 0xff)) {
- msg = "bad/missing register number";
- goto parse_error;
- }
- if (*p++ != ':') {
- msg = "missing ':'";
- goto parse_error;
- }
- q->val = simple_strtoul(p, &s, 16);
- digits = s - p;
- if (digits != 2 && digits != 4 && digits != 8) {
- msg = "bad data, 2/4/8 digits required";
- goto parse_error;
- }
- q->size = digits / 2;
-
- if (q->pci) {
-#ifdef CONFIG_BLK_DEV_IDEPCI
- if (q->reg & (q->size - 1)) {
- msg = "misaligned access";
- goto parse_error;
- }
-#else
- msg = "not a PCI device";
- goto parse_error;
-#endif /* CONFIG_BLK_DEV_IDEPCI */
- }
-
- q++;
-
- if (*s && !isspace(*s++)) {
- msg = "expected whitespace after data";
- goto parse_error;
- }
- while (isspace(*s))
- s++;
- }
-
- /*
- * What follows below is fucking insane, even for IDE people.
- * For now I've dealt with the obvious problems on the parsing
- * side, but IMNSHO we should simply remove the write access
- * to /proc/ide/.../config, killing that FPOS completely.
- */
-
- err = -EBUSY;
- timeout = jiffies + (3 * HZ);
- spin_lock_irqsave(&ide_lock, flags);
- while (mygroup->busy ||
- (mategroup && mategroup->busy)) {
- spin_unlock_irqrestore(&ide_lock, flags);
- if (time_after(jiffies, timeout)) {
- printk("/proc/ide/%s/config: channel(s) busy, cannot write\n", hwif->name);
- goto out1;
- }
- spin_lock_irqsave(&ide_lock, flags);
- }
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
- if (want_pci && (!hwif->pci_dev || hwif->pci_dev->vendor)) {
- spin_unlock_irqrestore(&ide_lock, flags);
- printk("proc_ide: PCI registers not accessible for %s\n",
- hwif->name);
- err = -EINVAL;
- goto out1;
- }
-#endif /* CONFIG_BLK_DEV_IDEPCI */
-
- for (r = prog; r < q; r++) {
- unsigned int reg = r->reg, val = r->val;
- if (r->pci) {
-#ifdef CONFIG_BLK_DEV_IDEPCI
- int rc = 0;
- struct pci_dev *dev = hwif->pci_dev;
- switch (q->size) {
- case 1: msg = "byte";
- rc = pci_write_config_byte(dev, reg, val);
- break;
- case 2: msg = "word";
- rc = pci_write_config_word(dev, reg, val);
- break;
- case 4: msg = "dword";
- rc = pci_write_config_dword(dev, reg, val);
- break;
- }
- if (rc) {
- spin_unlock_irqrestore(&ide_lock, flags);
- printk("proc_ide_write_config: error writing %s at bus %02x dev
%02x reg 0x%x value 0x%x\n",
- msg, dev->bus->number, dev->devfn, reg, val);
- printk("proc_ide_write_config: error %d\n", rc);
- err = -EIO;
- goto out1;
- }
-#endif /* CONFIG_BLK_DEV_IDEPCI */
- } else { /* not pci */
- switch (r->size) {
- case 1: hwif->OUTB(val, reg);
- break;
- case 2: hwif->OUTW(val, reg);
- break;
- case 4: hwif->OUTL(val, reg);
- break;
- }
- }
- }
- spin_unlock_irqrestore(&ide_lock, flags);
- err = count;
-out1:
- free_page((unsigned long)prog);
-out:
- free_page((unsigned long)buf);
- return err;
-
-parse_error:
- printk("parse error\n");
- printk("proc_ide: error: %s: '%s'\n", msg, start);
- err = -EINVAL;
- goto out1;
-}
-
-static int proc_ide_read_config
- (char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- char *out = page;
- int len;
-
-#ifdef CONFIG_BLK_DEV_IDEPCI
- ide_hwif_t *hwif = (ide_hwif_t *)data;
- struct pci_dev *dev = hwif->pci_dev;
- if ((hwif->pci_dev && hwif->pci_dev->vendor) && dev && dev->bus) {
- int reg = 0;
-
- out += sprintf(out, "pci bus %02x device %02x vendor %04x "
- "device %04x channel %d\n",
- dev->bus->number, dev->devfn,
- hwif->pci_dev->vendor, hwif->pci_dev->device,
- hwif->channel);
- do {
- u8 val;
- int rc = pci_read_config_byte(dev, reg, &val);
- if (rc) {
- printk("proc_ide_read_config: error %d reading"
- " bus %02x dev %02x reg 0x%02x\n",
- rc, dev->bus->number, dev->devfn, reg);
- out += sprintf(out, "??%c",
- (++reg & 0xf) ? ' ' : '\n');
- } else
- out += sprintf(out, "%02x%c",
- val, (++reg & 0xf) ? ' ' : '\n');
- } while (reg < 0x100);
- } else
-#endif /* CONFIG_BLK_DEV_IDEPCI */
- out += sprintf(out, "(none)\n");
- len = out - page;
- PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
-}
-
static int proc_ide_read_imodel
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
@@ -687,7 +431,6 @@
static ide_proc_entry_t hwif_entries[] = {
{ "channel", S_IFREG|S_IRUGO, proc_ide_read_channel, NULL },
- { "config", S_IFREG|S_IRUGO|S_IWUSR,proc_ide_read_config, proc_ide_write_config
},
{ "mate", S_IFREG|S_IRUGO, proc_ide_read_mate, NULL },
{ "model", S_IFREG|S_IRUGO, proc_ide_read_imodel, NULL },
{ NULL, 0, NULL, NULL }
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/ide.c 2004-10-22 19:29:05 +02:00
@@ -694,7 +694,6 @@
hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq;
hwif->ide_dma_host_on = tmp_hwif->ide_dma_host_on;
hwif->ide_dma_host_off = tmp_hwif->ide_dma_host_off;
- hwif->ide_dma_verbose = tmp_hwif->ide_dma_verbose;
hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq;
hwif->ide_dma_timeout = tmp_hwif->ide_dma_timeout;
diff -Nru a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
--- a/drivers/ide/pci/sgiioc4.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/pci/sgiioc4.c 2004-10-22 19:29:05 +02:00
@@ -332,17 +332,6 @@
}
static int
-sgiioc4_ide_dma_verbose(ide_drive_t * drive)
-{
- if (drive->using_dma == 1)
- printk(", UDMA(16)");
- else
- printk(", PIO");
-
- return 1;
-}
-
-static int
sgiioc4_ide_dma_lostirq(ide_drive_t * drive)
{
HWIF(drive)->resetproc(drive);
@@ -501,10 +490,7 @@
unsigned int count = 0, i = 1;
struct scatterlist *sg;
- if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
- hwif->sg_nents = i = ide_raw_build_sglist(drive, rq);
- else
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
+ hwif->sg_nents = i = ide_build_sglist(drive, rq);
if (!i)
return 0; /* sglist of length Zero */
@@ -623,7 +609,6 @@
hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on;
hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
- hwif->ide_dma_verbose = &sgiioc4_ide_dma_verbose;
hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
hwif->ide_dma_timeout = &__ide_dma_timeout;
hwif->INB = &sgiioc4_INB;
diff -Nru a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
--- a/drivers/ide/pci/siimage.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/pci/siimage.c 2004-10-22 19:29:05 +02:00
@@ -554,12 +554,6 @@
return 0;
}
-static int siimage_mmio_ide_dma_verbose (ide_drive_t *drive)
-{
- int temp = __ide_dma_verbose(drive);
- return temp;
-}
-
/**
* siimage_busproc - bus isolation ioctl
* @drive: drive to isolate/restore
@@ -1077,7 +1071,6 @@
if (hwif->mmio) {
hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq;
- hwif->ide_dma_verbose = &siimage_mmio_ide_dma_verbose;
} else {
hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq;
}
diff -Nru a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
--- a/drivers/ide/ppc/pmac.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/ide/ppc/pmac.c 2004-10-22 19:29:05 +02:00
@@ -1560,56 +1560,6 @@
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
/*
- * We build & map the sglist for a given request.
- */
-static int __pmac
-pmac_ide_build_sglist(ide_drive_t *drive, struct request *rq)
-{
- ide_hwif_t *hwif = HWIF(drive);
- struct scatterlist *sg = hwif->sg_table;
- int nents;
-
- nents = blk_rq_map_sg(drive->queue, rq, sg);
-
- if (rq_data_dir(rq) == READ)
- hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
- else
- hwif->sg_dma_direction = PCI_DMA_TODEVICE;
-
- return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
-}
-
-/*
- * Same as above but for a "raw" taskfile request
- */
-static int __pmac
-pmac_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
-{
- ide_hwif_t *hwif = HWIF(drive);
- struct scatterlist *sg = hwif->sg_table;
- int nents = 0;
- ide_task_t *args = rq->special;
- unsigned char *virt_addr = rq->buffer;
- int sector_count = rq->nr_sectors;
-
- if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
- hwif->sg_dma_direction = PCI_DMA_TODEVICE;
- else
- hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-
- if (sector_count > 128) {
- sg_init_one(&sg[nents], virt_addr, 128 * SECTOR_SIZE);
- nents++;
- virt_addr = virt_addr + (128 * SECTOR_SIZE);
- sector_count -= 128;
- }
- sg_init_one(&sg[nents], virt_addr, sector_count * SECTOR_SIZE);
- nents++;
-
- return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction);
-}
-
-/*
* pmac_ide_build_dmatable builds the DBDMA command list
* for a transfer and sets the DBDMA channel to point to it.
*/
@@ -1632,11 +1582,8 @@
while (readl(&dma->status) & RUN)
udelay(1);
- /* Build sglist */
- if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
- hwif->sg_nents = i = pmac_ide_raw_build_sglist(drive, rq);
- else
- hwif->sg_nents = i = pmac_ide_build_sglist(drive, rq);
+ hwif->sg_nents = i = ide_build_sglist(drive, rq);
+
if (!i)
return 0;
@@ -2078,7 +2025,6 @@
hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
hwif->ide_dma_host_off = &pmac_ide_dma_host_off;
hwif->ide_dma_host_on = &pmac_ide_dma_host_on;
- hwif->ide_dma_verbose = &__ide_dma_verbose;
hwif->ide_dma_timeout = &__ide_dma_timeout;
hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c 2004-10-22 19:29:05 +02:00
+++ b/drivers/scsi/ide-scsi.c 2004-10-22 19:29:05 +02:00
@@ -45,6 +45,7 @@
#include <linux/hdreg.h>
#include <linux/slab.h>
#include <linux/ide.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/bitops.h>
@@ -253,17 +254,6 @@
kfree(atapi_buf);
}
-static inline void idescsi_free_bio (struct bio *bio)
-{
- struct bio *bhp;
-
- while (bio) {
- bhp = bio;
- bio = bio->bi_next;
- bio_put(bhp);
- }
-}
-
static void hexdump(u8 *x, int len)
{
int i;
@@ -421,7 +411,6 @@
spin_lock_irqsave(host->host_lock, flags);
pc->done(pc->scsi_cmd);
spin_unlock_irqrestore(host->host_lock, flags);
- idescsi_free_bio(rq->bio);
kfree(pc);
kfree(rq);
scsi->pc = NULL;
@@ -585,6 +574,50 @@
return ide_started;
}
+static inline int idescsi_set_direction(idescsi_pc_t *pc)
+{
+ switch (pc->c[0]) {
+ case READ_6: case READ_10: case READ_12:
+ clear_bit(PC_WRITING, &pc->flags);
+ return 0;
+ case WRITE_6: case WRITE_10: case WRITE_12:
+ set_bit(PC_WRITING, &pc->flags);
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+static int idescsi_map_sg(ide_drive_t *drive, idescsi_pc_t *pc)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct scatterlist *sg, *scsi_sg;
+ int segments;
+
+ if (!pc->request_transfer || pc->request_transfer % 1024)
+ return 1;
+
+ if (idescsi_set_direction(pc))
+ return 1;
+
+ sg = hwif->sg_table;
+ scsi_sg = pc->scsi_cmd->request_buffer;
+ segments = pc->scsi_cmd->use_sg;
+
+ if (segments > hwif->sg_max_nents)
+ return 1;
+
+ if (!segments) {
+ hwif->sg_nents = 1;
+ sg_init_one(sg, pc->scsi_cmd->request_buffer, pc->request_transfer);
+ } else {
+ hwif->sg_nents = segments;
+ memcpy(sg, scsi_sg, sizeof(*sg) * segments);
+ }
+
+ return 0;
+}
+
/*
* Issue a packet command
*/
@@ -594,7 +627,6 @@
ide_hwif_t *hwif = drive->hwif;
atapi_feature_t feature;
atapi_bcount_t bcount;
- struct request *rq = pc->rq;
scsi->pc=pc; /* Set the current packet command */
pc->actually_transferred=0; /* We haven't transferred any data yet */
@@ -602,8 +634,11 @@
bcount.all = min(pc->request_transfer, 63 * 1024); /* Request to
transfer the entire buffer at once */
feature.all = 0;
- if (drive->using_dma && rq->bio)
+ if (drive->using_dma && !idescsi_map_sg(drive, pc)) {
+ hwif->sg_mapped = 1;
feature.b.dma = !hwif->dma_setup(drive);
+ hwif->sg_mapped = 0;
+ }
SELECT_DRIVE(drive);
if (IDE_CONTROL_REG)
@@ -775,81 +810,6 @@
return -EINVAL;
}
-static inline struct bio *idescsi_kmalloc_bio (int count)
-{
- struct bio *bh, *bhp, *first_bh;
-
- if ((first_bh = bhp = bh = bio_alloc(GFP_ATOMIC, 1)) == NULL)
- goto abort;
- bio_init(bh);
- bh->bi_vcnt = 1;
- while (--count) {
- if ((bh = bio_alloc(GFP_ATOMIC, 1)) == NULL)
- goto abort;
- bio_init(bh);
- bh->bi_vcnt = 1;
- bhp->bi_next = bh;
- bhp = bh;
- bh->bi_next = NULL;
- }
- return first_bh;
-abort:
- idescsi_free_bio (first_bh);
- return NULL;
-}
-
-static inline int idescsi_set_direction (idescsi_pc_t *pc)
-{
- switch (pc->c[0]) {
- case READ_6: case READ_10: case READ_12:
- clear_bit (PC_WRITING, &pc->flags);
- return 0;
- case WRITE_6: case WRITE_10: case WRITE_12:
- set_bit (PC_WRITING, &pc->flags);
- return 0;
- default:
- return 1;
- }
-}
-
-static inline struct bio *idescsi_dma_bio(ide_drive_t *drive, idescsi_pc_t *pc)
-{
- struct bio *bh = NULL, *first_bh = NULL;
- int segments = pc->scsi_cmd->use_sg;
- struct scatterlist *sg = pc->scsi_cmd->request_buffer;
-
- if (!drive->using_dma || !pc->request_transfer || pc->request_transfer % 1024)
- return NULL;
- if (idescsi_set_direction(pc))
- return NULL;
- if (segments) {
- if ((first_bh = bh = idescsi_kmalloc_bio (segments)) == NULL)
- return NULL;
-#if IDESCSI_DEBUG_LOG
- printk ("ide-scsi: %s: building DMA table, %d segments, %dkB
total\n", drive->name, segments, pc->request_transfer >> 10);
-#endif /* IDESCSI_DEBUG_LOG */
- while (segments--) {
- bh->bi_io_vec[0].bv_page = sg->page;
- bh->bi_io_vec[0].bv_len = sg->length;
- bh->bi_io_vec[0].bv_offset = sg->offset;
- bh->bi_size = sg->length;
- bh = bh->bi_next;
- sg++;
- }
- } else {
- if ((first_bh = bh = idescsi_kmalloc_bio (1)) == NULL)
- return NULL;
-#if IDESCSI_DEBUG_LOG
- printk ("ide-scsi: %s: building DMA table for a single buffer
(%dkB)\n", drive->name, pc->request_transfer >> 10);
-#endif /* IDESCSI_DEBUG_LOG */
- bh->bi_io_vec[0].bv_page = virt_to_page(pc->scsi_cmd->request_buffer);
- bh->bi_io_vec[0].bv_offset = offset_in_page(pc->scsi_cmd->request_buffer);
- bh->bi_io_vec[0].bv_len = pc->request_transfer;
- bh->bi_size = pc->request_transfer;
- }
- return first_bh;
-}
-
static inline int should_transform(ide_drive_t *drive, struct scsi_cmnd *cmd)
{
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
@@ -921,7 +881,6 @@
ide_init_drive_cmd (rq);
rq->special = (char *) pc;
- rq->bio = idescsi_dma_bio (drive, pc);
rq->flags = REQ_SPECIAL;
spin_unlock_irq(host->host_lock);
(void) ide_do_drive_cmd (drive, rq, ide_end);
@@ -975,7 +934,6 @@
*/
printk (KERN_ERR "ide-scsi: cmd aborted!\n");
- idescsi_free_bio(scsi->pc->rq->bio);
if (scsi->pc->rq->flags & REQ_SENSE)
kfree(scsi->pc->buffer);
kfree(scsi->pc->rq);
@@ -1024,7 +982,6 @@
/* kill current request */
blkdev_dequeue_request(req);
end_that_request_last(req);
- idescsi_free_bio(req->bio);
if (req->flags & REQ_SENSE)
kfree(scsi->pc->buffer);
kfree(scsi->pc);
diff -Nru a/include/linux/ide.h b/include/linux/ide.h
--- a/include/linux/ide.h 2004-10-22 19:29:05 +02:00
+++ b/include/linux/ide.h 2004-10-22 19:29:05 +02:00
@@ -874,7 +874,6 @@
int (*ide_dma_test_irq)(ide_drive_t *drive);
int (*ide_dma_host_on)(ide_drive_t *drive);
int (*ide_dma_host_off)(ide_drive_t *drive);
- int (*ide_dma_verbose)(ide_drive_t *drive);
int (*ide_dma_lostirq)(ide_drive_t *drive);
int (*ide_dma_timeout)(ide_drive_t *drive);
@@ -938,6 +937,7 @@
unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
unsigned no_dsc : 1; /* 0 default, 1 dsc_overlap disabled */
unsigned auto_poll : 1; /* supports nop auto-poll */
+ unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */
struct device gendev;
struct semaphore gendev_rel_sem; /* To deal with device release() */
@@ -1492,10 +1492,10 @@
int __ide_dma_bad_drive(ide_drive_t *);
int __ide_dma_good_drive(ide_drive_t *);
int __ide_dma_off(ide_drive_t *);
+void ide_dma_verbose(ide_drive_t *);
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
extern int ide_build_sglist(ide_drive_t *, struct request *);
-extern int ide_raw_build_sglist(ide_drive_t *, struct request *);
extern int ide_build_dmatable(ide_drive_t *, struct request *);
extern void ide_destroy_dmatable(ide_drive_t *);
extern ide_startstop_t ide_dma_intr(ide_drive_t *);
@@ -1511,13 +1511,13 @@
extern void ide_dma_start(ide_drive_t *);
extern int __ide_dma_end(ide_drive_t *);
extern int __ide_dma_test_irq(ide_drive_t *);
-extern int __ide_dma_verbose(ide_drive_t *);
extern int __ide_dma_lostirq(ide_drive_t *);
extern int __ide_dma_timeout(ide_drive_t *);
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
#else
static inline int __ide_dma_off(ide_drive_t *drive) { return 0; }
+static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
#endif /* CONFIG_BLK_DEV_IDEDMA */
#ifndef CONFIG_BLK_DEV_IDEDMA_PCI
next reply other threads:[~2004-10-22 17:38 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-10-22 17:38 Bartlomiej Zolnierkiewicz [this message]
2004-10-22 18:07 ` [BK PATCHES] ide-2.6 update Russell King
2004-10-22 18:17 ` Bartlomiej Zolnierkiewicz
-- strict thread matches above, loose matches on Subject: below --
2005-04-02 15:22 Bartlomiej Zolnierkiewicz
2005-03-18 16:22 Bartlomiej Zolnierkiewicz
2005-03-10 17:45 Bartlomiej Zolnierkiewicz
2005-02-24 11:20 Bartlomiej Zolnierkiewicz
2005-02-20 14:24 Bartlomiej Zolnierkiewicz
2005-02-06 14:03 Bartlomiej Zolnierkiewicz
2005-02-03 16:47 Bartlomiej Zolnierkiewicz
2005-01-15 11:40 Bartlomiej Zolnierkiewicz
2005-01-07 3:48 Bartlomiej Zolnierkiewicz
2004-12-30 22:32 Bartlomiej Zolnierkiewicz
2004-12-10 19:40 Bartlomiej Zolnierkiewicz
2004-12-10 21:15 ` Bartlomiej Zolnierkiewicz
2004-12-14 18:23 ` Enrico Scholz
2004-11-17 23:41 Bartlomiej Zolnierkiewicz
2004-11-06 0:54 Bartlomiej Zolnierkiewicz
2004-11-01 18:26 Bartlomiej Zolnierkiewicz
2004-10-31 2:27 Kevin Freeman
2004-10-29 18:00 Bartlomiej Zolnierkiewicz
2004-10-27 16:10 Chuck Ebbert
2004-10-27 16:18 ` Alan Cox
2004-10-27 18:58 ` Gene Heskett
2004-10-28 20:19 ` Eric Mudama
2004-10-30 15:48 ` tabris
2004-10-27 16:29 ` Bartlomiej Zolnierkiewicz
2004-10-27 13:07 Bartlomiej Zolnierkiewicz
2004-10-27 13:34 ` CaT
2004-10-27 13:51 ` Bartlomiej Zolnierkiewicz
2004-10-27 14:33 ` Mikael Pettersson
2004-10-27 14:49 ` Bartlomiej Zolnierkiewicz
2004-10-27 14:29 ` J.A. Magallon
2004-10-27 15:07 ` Bartlomiej Zolnierkiewicz
2004-10-27 16:15 ` Gene Heskett
2004-10-27 16:22 ` Bartlomiej Zolnierkiewicz
2004-10-27 17:05 ` Gene Heskett
2004-10-27 17:02 ` Randy.Dunlap
2004-10-27 18:17 ` Gene Heskett
2004-10-27 17:15 ` Bartlomiej Zolnierkiewicz
2004-10-27 18:19 ` Gene Heskett
2004-10-27 17:20 ` Linus Torvalds
2004-10-27 18:26 ` Gene Heskett
2004-10-27 18:41 ` Linus Torvalds
2004-10-27 19:03 ` Gene Heskett
2004-10-28 6:45 ` Gene Heskett
2004-10-24 12:08 Bartlomiej Zolnierkiewicz
2004-10-24 19:48 ` James Cloos
2004-10-24 20:15 ` Bartlomiej Zolnierkiewicz
2004-10-24 20:51 ` James Cloos
2004-10-25 19:18 ` Bill Davidsen
2004-10-25 19:18 ` Bill Davidsen
2004-10-22 0:34 Bartlomiej Zolnierkiewicz
2004-10-20 17:42 Bartlomiej Zolnierkiewicz
2004-10-19 20:47 Bartlomiej Zolnierkiewicz
2004-10-10 16:10 Bartlomiej Zolnierkiewicz
2004-10-01 18:43 Bartlomiej Zolnierkiewicz
2004-09-23 18:49 Bartlomiej Zolnierkiewicz
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=58cb370e04102210385ca8b554@mail.gmail.com \
--to=bzolnier@gmail.com \
--cc=linux-ide@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/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.