diff --git a/arch/cris/arch-v10/drivers/ide.c b/arch/cris/arch-v10/drivers/ide.c index 473e4d1332020e933cc1dad4ea7d19ad2011910f..cd97e6f9071c1dbceef2b6bb0853e3181939979d 100644 --- a/arch/cris/arch-v10/drivers/ide.c +++ b/arch/cris/arch-v10/drivers/ide.c @@ -656,15 +656,9 @@ static int e100_ide_build_dmatable (ide_drive_t *drive) 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 --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index a24120ef0c6b4c7a2848a14333343253122f29e1..dc08dcc6e698b852a94698875c643e81f0291637 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -212,33 +212,18 @@ static void icside_build_sglist(ide_drive_t *drive, struct request *rq) 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 @@ static int icside_dma_test_irq(ide_drive_t *drive) 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 @@ static void icside_dma_init(ide_hwif_t *hwif) 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 --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index d6397420196271a4add976eaa70540a4f8ac9172..0f8516568457a58e5b766ba5d2474b56c8576748 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -3039,10 +3039,9 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive) 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 --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 2108a97f6e30d5d1e94dddc5107ebd7a34cf852a..9599f8bcf5ab212736a7a20a2a0350541074fa87 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -1244,7 +1244,7 @@ static void idedisk_setup (ide_drive_t *drive) 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 --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 8157fb812d74b81d3d65632728c1d0a23afb56d2..3ee78ef9b0be69d363236cd758ee14a39c0cede2 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -207,66 +207,22 @@ int 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, 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 * @@ -288,10 +244,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq) 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 @@ int __ide_dma_good_drive (ide_drive_t *drive) 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 @@ int __ide_dma_verbose (ide_drive_t *drive) 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 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p 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 --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index d05160722f7381c087c5eca178ac2723bbdfa3c3..ebb9280daa83abc71036e0ba78780c34cfd99514 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -680,6 +680,9 @@ void ide_map_sg(ide_drive_t *drive, struct request *rq) 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 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) 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 --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 145c34930adbd54b8439d3e20d4ce5731d56f25c..1dabe2cbc4f28491d46d47c5b1acec2ec847383c 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -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 @@ void destroy_proc_ide_drives(ide_hwif_t *hwif) 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 --git a/drivers/ide/ide.c b/drivers/ide/ide.c index fc8f056a31fd5f00f2aa81a8937c3adaa5570510..34ef6769162bc692812ea6613bd6c192311c8937 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -694,7 +694,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) 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 --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 88ca26a2c2453fce8043eb8395861359ed9640a4..ed1ea5b7545b7981fc763f87158229b3fb3daa9f 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -331,17 +331,6 @@ sgiioc4_ide_dma_host_off(ide_drive_t * drive) return 0; } -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) { @@ -501,10 +490,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) 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 @@ ide_init_sgiioc4(ide_hwif_t * hwif) 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 --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 6c874989bb616ce6b4c974ee56264ace9bf4fd16..bdf18d67e481022a94d11abd2f44b4264048695a 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -554,12 +554,6 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive) 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 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) 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 --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 33a1690417706a34101a712ea914f04803413e47..1387f90575500ee1a404af5bed5109ea264b1b8e 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1559,56 +1559,6 @@ pmac_ide_probe(void) #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 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq) 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 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) 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 --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index ea0527e9837e7f2596f30b53cd3a4cfc81f0e8c6..18e091a0e587c449c3fd9be968a6054b51533df9 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -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 @@ static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc) 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 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) 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 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) 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 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) 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 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) 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 @@ static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg) 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 @@ static int idescsi_queue (struct scsi_cmnd *cmd, 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 @@ static int idescsi_eh_abort (struct scsi_cmnd *cmd) */ 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 @@ static int idescsi_eh_reset (struct scsi_cmnd *cmd) /* 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 --git a/include/linux/ide.h b/include/linux/ide.h index f4bafe0cd0fb73796f21b1362a97c8f831a1e95e..284e9ab25aa14c16e939de5581b0c3ebec8d82de 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -874,7 +874,6 @@ typedef struct hwif_s { 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 @@ typedef struct hwif_s { 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 @@ void ide_init_sg_cmd(ide_drive_t *, struct request *); 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 int ide_dma_setup(ide_drive_t *); 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