From 635f0258e5ae526034486b4ae9020e64bfb7d27e Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Oct 2008 09:43:54 +0000 Subject: [ARM] clps7500: remove support The CLPS7500 platform has not built since 2.6.22-git7 and there seems to be no interest in fixing it. So, remove the platform support. Signed-off-by: Russell King --- drivers/ide/Kconfig | 2 +- drivers/ide/ide_arm.c | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 6d7401772a8..57630402ea6 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -732,7 +732,7 @@ config BLK_DEV_IDE_TX4939 config IDE_ARM tristate "ARM IDE support" - depends on ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) + depends on ARM && (ARCH_RPC || ARCH_SHARK) default y config BLK_DEV_IDE_ICSIDE diff --git a/drivers/ide/ide_arm.c b/drivers/ide/ide_arm.c index f728f2927b5..bdcac94d7c1 100644 --- a/drivers/ide/ide_arm.c +++ b/drivers/ide/ide_arm.c @@ -15,15 +15,8 @@ #define DRV_NAME "ide_arm" -#ifdef CONFIG_ARCH_CLPS7500 -# include -# -# define IDE_ARM_IO (ISASLOT_IO + 0x1f0) -# define IDE_ARM_IRQ IRQ_ISA_14 -#else -# define IDE_ARM_IO 0x1f0 -# define IDE_ARM_IRQ IRQ_HARDDISK -#endif +#define IDE_ARM_IO 0x1f0 +#define IDE_ARM_IRQ IRQ_HARDDISK static int __init ide_arm_init(void) { -- cgit From ecdbc6906e4c31bc387c64490e31ae3e0f929479 Mon Sep 17 00:00:00 2001 From: Robin Holt Date: Mon, 8 Dec 2008 15:47:20 -0800 Subject: [IA64] Clear up section mismatch for ioc4_ide_attach_one. The generic_defconfig has three section mismatches. This clears up ioc4_ide_attach_one(). Signed-off-by: Robin Holt Signed-off-by: Mike Reid Signed-off-by: Tony Luck --- drivers/ide/sgiioc4.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c index 7defa0ae201..a687a7dfea6 100644 --- a/drivers/ide/sgiioc4.c +++ b/drivers/ide/sgiioc4.c @@ -550,7 +550,7 @@ static const struct ide_dma_ops sgiioc4_dma_ops = { .dma_timeout = ide_dma_timeout, }; -static const struct ide_port_info sgiioc4_port_info __devinitdata = { +static const struct ide_port_info sgiioc4_port_info __devinitconst = { .name = DRV_NAME, .chipset = ide_pci, .init_dma = ide_dma_sgiioc4, @@ -633,7 +633,7 @@ out: return ret; } -int +int __devinit ioc4_ide_attach_one(struct ioc4_driver_data *idd) { /* PCI-RT does not bring out IDE connection. @@ -645,7 +645,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd) return pci_init_sgiioc4(idd->idd_pdev); } -static struct ioc4_submodule ioc4_ide_submodule = { +static struct ioc4_submodule __devinitdata ioc4_ide_submodule = { .is_name = "IOC4_ide", .is_owner = THIS_MODULE, .is_probe = ioc4_ide_attach_one, -- cgit From 9ecab6e5bf87f96dc2fa89cc9e8d5576fbde4325 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 22 Dec 2008 23:05:06 +0100 Subject: drivers/ide/{cs5530.c,sc1200.c}: Move a dereference below a NULL test In each case, if the NULL test is necessary, then the dereference should be moved below the NULL test. The semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @@ type T; expression E; identifier i,fld; statement S; @@ - T i = E->fld; + T i; ... when != E when != i if (E == NULL) S + i = E->fld; // Signed-off-by: Julia Lawall Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/cs5530.c | 3 ++- drivers/ide/sc1200.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c index 53f079cc00a..d8ede85fe17 100644 --- a/drivers/ide/cs5530.c +++ b/drivers/ide/cs5530.c @@ -81,11 +81,12 @@ static u8 cs5530_udma_filter(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; ide_drive_t *mate = ide_get_pair_dev(drive); - u16 *mateid = mate->id; + u16 *mateid; u8 mask = hwif->ultra_mask; if (mate == NULL) goto out; + mateid = mate->id; if (ata_id_has_dma(mateid) && __ide_dma_bad_drive(mate) == 0) { if ((mateid[ATA_ID_FIELD_VALID] & 4) && diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c index f1a8758e3a9..ec7f766ef5e 100644 --- a/drivers/ide/sc1200.c +++ b/drivers/ide/sc1200.c @@ -104,11 +104,12 @@ static u8 sc1200_udma_filter(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; ide_drive_t *mate = ide_get_pair_dev(drive); - u16 *mateid = mate->id; + u16 *mateid; u8 mask = hwif->ultra_mask; if (mate == NULL) goto out; + mateid = mate->id; if (ata_id_has_dma(mateid) && __ide_dma_bad_drive(mate) == 0) { if ((mateid[ATA_ID_FIELD_VALID] & 4) && -- cgit From 429dbf53bca49b110f1058f0d9417a59115c41b8 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Tue, 18 Nov 2008 20:45:20 +0100 Subject: m68k: machw.h cleanup Remove some more cruft from machw.h and drop the #include where it isn't needed. Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven --- drivers/ide/macide.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/ide') diff --git a/drivers/ide/macide.c b/drivers/ide/macide.c index 43f97cc1d30..3c60064f1d4 100644 --- a/drivers/ide/macide.c +++ b/drivers/ide/macide.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include -- cgit From a0fce792b55b260589c3d77293a224e84395ec07 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 29 Dec 2008 20:27:28 +0100 Subject: tx4939ide: Do not use zero count PRD entry This fixes data corruption on some heavy load. Signed-off-by: Atsushi Nemoto Cc: stable Cc: sshtylyov@ru.mvista.com Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/tx4939ide.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/ide') diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c index bafb7d1a22e..30d0d256230 100644 --- a/drivers/ide/tx4939ide.c +++ b/drivers/ide/tx4939ide.c @@ -259,6 +259,12 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq) bcount = 0x10000 - (cur_addr & 0xffff); if (bcount > cur_len) bcount = cur_len; + /* + * This workaround for zero count seems required. + * (standard ide_build_dmatable do it too) + */ + if ((bcount & 0xffff) == 0x0000) + bcount = 0x8000; *table++ = bcount & 0xffff; *table++ = cur_addr; cur_addr += bcount; -- cgit From f26f6ceacaaf017a677138cbca7ab076b565ca87 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 29 Dec 2008 20:27:29 +0100 Subject: tx493[89]ide: Fix length for __ide_flush_dcache_range This fixes data corruption on PIO mode. Signed-off-by: Atsushi Nemoto Cc: stable Cc: sshtylyov@ru.mvista.com Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/tx4938ide.c | 4 ++-- drivers/ide/tx4939ide.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c index 9120063e8f8..13b63e7fa35 100644 --- a/drivers/ide/tx4938ide.c +++ b/drivers/ide/tx4938ide.c @@ -181,7 +181,7 @@ static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq, while (count--) *ptr++ = cpu_to_le16(__raw_readw((void __iomem *)port)); - __ide_flush_dcache_range((unsigned long)buf, count * 2); + __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq, @@ -195,7 +195,7 @@ static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq, __raw_writew(le16_to_cpu(*ptr), (void __iomem *)port); ptr++; } - __ide_flush_dcache_range((unsigned long)buf, count * 2); + __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } static const struct ide_tp_ops tx4938ide_tp_ops = { diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c index 30d0d256230..97cd9e0f66f 100644 --- a/drivers/ide/tx4939ide.c +++ b/drivers/ide/tx4939ide.c @@ -564,7 +564,7 @@ static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq, while (count--) *ptr++ = cpu_to_le16(__raw_readw((void __iomem *)port)); - __ide_flush_dcache_range((unsigned long)buf, count * 2); + __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } static void tx4939ide_output_data_swap(ide_drive_t *drive, struct request *rq, @@ -578,7 +578,7 @@ static void tx4939ide_output_data_swap(ide_drive_t *drive, struct request *rq, __raw_writew(le16_to_cpu(*ptr), (void __iomem *)port); ptr++; } - __ide_flush_dcache_range((unsigned long)buf, count * 2); + __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } static const struct ide_tp_ops tx4939ide_tp_ops = { -- cgit From 0e63a588fc3d6a5e6bb66bacaeb11cd9093141f8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:29 +0100 Subject: ide: fix IDE ACPI regression breaking suspend Commit 4dde4492d850a4c9bcaa92e5bd7f4eebe3e2f5ab ("ide: make drive->id an union (take 2)") accidentally introduced an IDE ACPI regression which at least on some machines confuses ACPI and breaks suspend. Fix it. Fixes kernel.org bug #12279: http://bugzilla.kernel.org/show_bug.cgi?id=12279 [ Sorry about the bug (IDE ACPI is not used by default so it managed to slip in). Still it is kind of surprising that the bug breaks suspend as it shouldn't impact anything except IDE ACPI (it seems that it uncovered either some ACPI/PM deficiency or a BIOS bug). ] Reported-and-bisected-by: David Roka Tested-by: David Roka Cc: Rafael J. Wysocki Cc: Len Brown Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-acpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 244a8a052ce..fd4a3643305 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -615,10 +615,10 @@ void ide_acpi_push_timing(ide_hwif_t *hwif) in_params[0].buffer.length = sizeof(struct GTM_buffer); in_params[0].buffer.pointer = (u8 *)&hwif->acpidata->gtm; in_params[1].type = ACPI_TYPE_BUFFER; - in_params[1].buffer.length = sizeof(ATA_ID_WORDS * 2); + in_params[1].buffer.length = ATA_ID_WORDS * 2; in_params[1].buffer.pointer = (u8 *)&master->idbuff; in_params[2].type = ACPI_TYPE_BUFFER; - in_params[2].buffer.length = sizeof(ATA_ID_WORDS * 2); + in_params[2].buffer.length = ATA_ID_WORDS * 2; in_params[2].buffer.pointer = (u8 *)&slave->idbuff; /* Output buffer: _STM has no output */ -- cgit From 3e0e29f7373ec96a1bd972790649524af7353f42 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:29 +0100 Subject: ide: unify ide_intr()'s exit points Just a preparation for future changes. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index cc35d6dbd41..35b62588280 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1363,14 +1363,13 @@ irqreturn_t ide_intr (int irq, void *dev_id) ide_drive_t *drive; ide_handler_t *handler; ide_startstop_t startstop; + irqreturn_t irq_ret = IRQ_NONE; spin_lock_irqsave(&ide_lock, flags); hwif = hwgroup->hwif; - if (!ide_ack_intr(hwif)) { - spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_NONE; - } + if (!ide_ack_intr(hwif)) + goto out; if ((handler = hwgroup->handler) == NULL || hwgroup->polling) { /* @@ -1406,9 +1405,9 @@ irqreturn_t ide_intr (int irq, void *dev_id) (void)hwif->tp_ops->read_status(hwif); #endif /* CONFIG_BLK_DEV_IDEPCI */ } - spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_NONE; + goto out; } + drive = hwgroup->drive; if (!drive) { /* @@ -1417,10 +1416,10 @@ irqreturn_t ide_intr (int irq, void *dev_id) * * [Note - this can occur if the drive is hot unplugged] */ - spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_HANDLED; + goto out_handled; } - if (!drive_is_ready(drive)) { + + if (!drive_is_ready(drive)) /* * This happens regularly when we share a PCI IRQ with * another device. Unfortunately, it can also happen @@ -1428,9 +1427,8 @@ irqreturn_t ide_intr (int irq, void *dev_id) * their status register is up to date. Hopefully we have * enough advance overhead that the latter isn't a problem. */ - spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_NONE; - } + goto out; + if (!hwgroup->busy) { hwgroup->busy = 1; /* paranoia */ printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name); @@ -1467,8 +1465,11 @@ irqreturn_t ide_intr (int irq, void *dev_id) "on exit\n", drive->name); } } +out_handled: + irq_ret = IRQ_HANDLED; +out: spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_HANDLED; + return irq_ret; } /** -- cgit From 1f473e9c92ea458e60494561a2065a358b7239bb Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:29 +0100 Subject: ide: IDE settings don't need an ide_lock held IDE settings are protected by ide_setting_mtx mutex so there is no need to hold ide_lock in ide_setting_ioctl(), ide_read_setting() and ide_proc_unregister_driver(). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-ioctls.c | 3 --- drivers/ide/ide-proc.c | 25 ++++--------------------- 2 files changed, 4 insertions(+), 24 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index fcde16bb53a..f9034765aa1 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -19,7 +19,6 @@ int ide_setting_ioctl(ide_drive_t *drive, struct block_device *bdev, const struct ide_ioctl_devset *s) { const struct ide_devset *ds; - unsigned long flags; int err = -EOPNOTSUPP; for (; (ds = s->setting); s++) { @@ -33,9 +32,7 @@ int ide_setting_ioctl(ide_drive_t *drive, struct block_device *bdev, read_val: mutex_lock(&ide_setting_mtx); - spin_lock_irqsave(&ide_lock, flags); err = ds->get(drive); - spin_unlock_irqrestore(&ide_lock, flags); mutex_unlock(&ide_setting_mtx); return err >= 0 ? put_user(err, (long __user *)arg) : err; diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index f3cddd1b2f8..dd899e1f384 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -155,13 +155,8 @@ static int ide_read_setting(ide_drive_t *drive, const struct ide_devset *ds = setting->setting; int val = -EINVAL; - if (ds->get) { - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); + if (ds->get) val = ds->get(drive); - spin_unlock_irqrestore(&ide_lock, flags); - } return val; } @@ -583,31 +578,19 @@ EXPORT_SYMBOL(ide_proc_register_driver); * Clean up the driver specific /proc files and IDE settings * for a given drive. * - * Takes ide_setting_mtx and ide_lock. - * Caller must hold none of the locks. + * Takes ide_setting_mtx. */ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { - unsigned long flags; - ide_remove_proc_entries(drive->proc, driver->proc_entries(drive)); mutex_lock(&ide_setting_mtx); - spin_lock_irqsave(&ide_lock, flags); /* - * ide_setting_mtx protects the settings list - * ide_lock protects the use of settings - * - * so we need to hold both, ide_settings_sem because we want to - * modify the settings list, and ide_lock because we cannot take - * a setting out that is being used. - * - * OTOH both ide_{read,write}_setting are only ever used under - * ide_setting_mtx. + * ide_setting_mtx protects both the settings list and the use + * of settings (we cannot take a setting out that is being used). */ drive->settings = NULL; - spin_unlock_irqrestore(&ide_lock, flags); mutex_unlock(&ide_setting_mtx); } EXPORT_SYMBOL(ide_proc_unregister_driver); -- cgit From 44e312310889145b47311a311d3faf2488349116 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:30 +0100 Subject: ide: __ide_port_unregister_devices() doesn't need an ide_lock held [ and ide_cfg_mtx mutex provides a sufficient protection for callers ] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 04f8f13cb9d..bca6877ee6a 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -130,7 +130,6 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif) } } -/* Called with ide_lock held. */ static void __ide_port_unregister_devices(ide_hwif_t *hwif) { int i; @@ -139,10 +138,8 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif) ide_drive_t *drive = &hwif->drives[i]; if (drive->dev_flags & IDE_DFLAG_PRESENT) { - spin_unlock_irq(&ide_lock); device_unregister(&drive->gendev); wait_for_completion(&drive->gendev_rel_comp); - spin_lock_irq(&ide_lock); } } } @@ -150,11 +147,9 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif) void ide_port_unregister_devices(ide_hwif_t *hwif) { mutex_lock(&ide_cfg_mtx); - spin_lock_irq(&ide_lock); __ide_port_unregister_devices(hwif); hwif->present = 0; ide_port_init_devices_data(hwif); - spin_unlock_irq(&ide_lock); mutex_unlock(&ide_cfg_mtx); } EXPORT_SYMBOL_GPL(ide_port_unregister_devices); @@ -192,12 +187,10 @@ void ide_unregister(ide_hwif_t *hwif) mutex_lock(&ide_cfg_mtx); - spin_lock_irq(&ide_lock); if (hwif->present) { __ide_port_unregister_devices(hwif); hwif->present = 0; } - spin_unlock_irq(&ide_lock); ide_proc_unregister_port(hwif); -- cgit From 1d0bf587df5b17bb93b32d760171417883ca907f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:30 +0100 Subject: ide: ide_hwgroup_t.rq doesn't need an ide_lock held While at it: - no need to check for hwgroup presence in ide_dump_opcode() Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 12 ++++++++---- drivers/ide/ide-io.c | 40 +++++++++++++++++++--------------------- drivers/ide/ide-lib.c | 7 +------ 3 files changed, 28 insertions(+), 31 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 42ab6d8715f..31f398577ed 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -317,7 +317,8 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st) static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) { ide_hwif_t *hwif = drive->hwif; - struct request *rq = hwif->hwgroup->rq; + ide_hwgroup_t *hwgroup = hwif->hwgroup; + struct request *rq = hwgroup->rq; int stat, err, sense_key; /* check for errors */ @@ -508,9 +509,10 @@ end_request: spin_lock_irqsave(&ide_lock, flags); blkdev_dequeue_request(rq); - HWGROUP(drive)->rq = NULL; spin_unlock_irqrestore(&ide_lock, flags); + hwgroup->rq = NULL; + cdrom_queue_request_sense(drive, rq->sense, rq); } else cdrom_end_request(drive, 0); @@ -950,7 +952,8 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq) static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct request *rq = HWGROUP(drive)->rq; + ide_hwgroup_t *hwgroup = hwif->hwgroup; + struct request *rq = hwgroup->rq; xfer_func_t *xferfunc; ide_expiry_t *expiry = NULL; int dma_error = 0, dma, stat, thislen, uptodate = 0; @@ -1157,8 +1160,9 @@ end_request: spin_lock_irqsave(&ide_lock, flags); if (__blk_end_request(rq, 0, dlen)) BUG(); - HWGROUP(drive)->rq = NULL; spin_unlock_irqrestore(&ide_lock, flags); + + hwgroup->rq = NULL; } else { if (!uptodate) rq->cmd_flags |= REQ_FAILED; diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 35b62588280..8afe7b15dec 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -107,17 +107,10 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) { unsigned int nr_bytes = nr_sectors << 9; - struct request *rq; + struct request *rq = drive->hwif->hwgroup->rq; unsigned long flags; int ret = 1; - /* - * room for locking improvements here, the calls below don't - * need the queue lock held at all - */ - spin_lock_irqsave(&ide_lock, flags); - rq = HWGROUP(drive)->rq; - if (!nr_bytes) { if (blk_pc_request(rq)) nr_bytes = rq->data_len; @@ -125,9 +118,10 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) nr_bytes = rq->hard_cur_sectors << 9; } + spin_lock_irqsave(&ide_lock, flags); ret = __ide_end_request(drive, rq, uptodate, nr_bytes, 1); - spin_unlock_irqrestore(&ide_lock, flags); + return ret; } EXPORT_SYMBOL(ide_end_request); @@ -245,8 +239,9 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, unsigned long flags; int ret; - spin_lock_irqsave(&ide_lock, flags); BUG_ON(!blk_rq_started(rq)); + + spin_lock_irqsave(&ide_lock, flags); ret = __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0); spin_unlock_irqrestore(&ide_lock, flags); @@ -278,7 +273,11 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) drive->dev_flags &= ~IDE_DFLAG_BLOCKED; blk_start_queue(drive->queue); } - HWGROUP(drive)->rq = NULL; + spin_unlock_irqrestore(&ide_lock, flags); + + drive->hwif->hwgroup->rq = NULL; + + spin_lock_irqsave(&ide_lock, flags); if (__blk_end_request(rq, 0, 0)) BUG(); spin_unlock_irqrestore(&ide_lock, flags); @@ -300,12 +299,9 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) { + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; + struct request *rq = hwgroup->rq; unsigned long flags; - struct request *rq; - - spin_lock_irqsave(&ide_lock, flags); - rq = HWGROUP(drive)->rq; - spin_unlock_irqrestore(&ide_lock, flags); if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *task = (ide_task_t *)rq->special; @@ -333,15 +329,16 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) return; } - spin_lock_irqsave(&ide_lock, flags); - HWGROUP(drive)->rq = NULL; + hwgroup->rq = NULL; + rq->errors = err; + + spin_lock_irqsave(&ide_lock, flags); if (unlikely(__blk_end_request(rq, (rq->errors ? -EIO : 0), blk_rq_bytes(rq)))) BUG(); spin_unlock_irqrestore(&ide_lock, flags); } - EXPORT_SYMBOL(ide_end_drive_cmd); static void ide_kill_rq(ide_drive_t *drive, struct request *rq) @@ -1489,11 +1486,12 @@ out: void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) { + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; unsigned long flags; - ide_hwgroup_t *hwgroup = HWGROUP(drive); - spin_lock_irqsave(&ide_lock, flags); hwgroup->rq = NULL; + + spin_lock_irqsave(&ide_lock, flags); __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); blk_start_queueing(drive->queue); spin_unlock_irqrestore(&ide_lock, flags); diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 9fc4cfb2a27..1932119dfa0 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -277,14 +277,9 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) static void ide_dump_opcode(ide_drive_t *drive) { - struct request *rq; + struct request *rq = drive->hwif->hwgroup->rq; ide_task_t *task = NULL; - spin_lock(&ide_lock); - rq = NULL; - if (HWGROUP(drive)) - rq = HWGROUP(drive)->rq; - spin_unlock(&ide_lock); if (!rq) return; -- cgit From a72b2147ec9e77be68308ba06190603550d1cb61 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:30 +0100 Subject: ide: push ide_lock to __ide_end_request() __ide_end_request() needs ide_lock only for __blk_end_request() call so push ide_lock taking inside __ide_end_requests(). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 8afe7b15dec..70916353601 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -58,6 +58,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, unsigned int nr_bytes, int dequeue) { + unsigned long flags; int ret = 1; int error = 0; @@ -84,11 +85,13 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, ide_dma_on(drive); } - if (!__blk_end_request(rq, error, nr_bytes)) { - if (dequeue) - HWGROUP(drive)->rq = NULL; + spin_lock_irqsave(&ide_lock, flags); + if (!__blk_end_request(rq, error, nr_bytes)) ret = 0; - } + spin_unlock_irqrestore(&ide_lock, flags); + + if (ret == 0 && dequeue) + drive->hwif->hwgroup->rq = NULL; return ret; } @@ -108,8 +111,6 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) { unsigned int nr_bytes = nr_sectors << 9; struct request *rq = drive->hwif->hwgroup->rq; - unsigned long flags; - int ret = 1; if (!nr_bytes) { if (blk_pc_request(rq)) @@ -118,11 +119,7 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) nr_bytes = rq->hard_cur_sectors << 9; } - spin_lock_irqsave(&ide_lock, flags); - ret = __ide_end_request(drive, rq, uptodate, nr_bytes, 1); - spin_unlock_irqrestore(&ide_lock, flags); - - return ret; + return __ide_end_request(drive, rq, uptodate, nr_bytes, 1); } EXPORT_SYMBOL(ide_end_request); @@ -236,16 +233,9 @@ out_do_tf: int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, int uptodate, int nr_sectors) { - unsigned long flags; - int ret; - BUG_ON(!blk_rq_started(rq)); - spin_lock_irqsave(&ide_lock, flags); - ret = __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0); - spin_unlock_irqrestore(&ide_lock, flags); - - return ret; + return __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0); } EXPORT_SYMBOL_GPL(ide_end_dequeued_request); -- cgit From 3c8a2cce47c6813383c9e38134e31f7e5f72e9d8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:31 +0100 Subject: ide: ide_lock + __blk_end_request() -> blk_end_request() Use blk_end_request() instead of ide_lock + __blk_end_request() in cdrom_end_request(), cdrom_newpc_intr(), __ide_end_request(), ide_complete_pm_request() and ide_end_drive_cmd(). [ ide_lock is currently also used as queue lock ] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 12 +++--------- drivers/ide/ide-io.c | 16 ++++------------ 2 files changed, 7 insertions(+), 21 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 31f398577ed..ac607bbde45 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -262,7 +262,6 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) struct request *failed = (struct request *) rq->buffer; struct cdrom_info *info = drive->driver_data; void *sense = &info->sense_data; - unsigned long flags; if (failed) { if (failed->sense) { @@ -278,11 +277,9 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) failed->hard_nr_sectors)) BUG(); } else { - spin_lock_irqsave(&ide_lock, flags); - if (__blk_end_request(failed, -EIO, - failed->data_len)) + if (blk_end_request(failed, -EIO, + failed->data_len)) BUG(); - spin_unlock_irqrestore(&ide_lock, flags); } } else cdrom_analyze_sense_data(drive, NULL, sense); @@ -1151,16 +1148,13 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) end_request: if (blk_pc_request(rq)) { - unsigned long flags; unsigned int dlen = rq->data_len; if (dma) rq->data_len = 0; - spin_lock_irqsave(&ide_lock, flags); - if (__blk_end_request(rq, 0, dlen)) + if (blk_end_request(rq, 0, dlen)) BUG(); - spin_unlock_irqrestore(&ide_lock, flags); hwgroup->rq = NULL; } else { diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 70916353601..4a6576f6146 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -58,7 +58,6 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, unsigned int nr_bytes, int dequeue) { - unsigned long flags; int ret = 1; int error = 0; @@ -85,10 +84,8 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, ide_dma_on(drive); } - spin_lock_irqsave(&ide_lock, flags); - if (!__blk_end_request(rq, error, nr_bytes)) + if (!blk_end_request(rq, error, nr_bytes)) ret = 0; - spin_unlock_irqrestore(&ide_lock, flags); if (ret == 0 && dequeue) drive->hwif->hwgroup->rq = NULL; @@ -267,10 +264,8 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) drive->hwif->hwgroup->rq = NULL; - spin_lock_irqsave(&ide_lock, flags); - if (__blk_end_request(rq, 0, 0)) + if (blk_end_request(rq, 0, 0)) BUG(); - spin_unlock_irqrestore(&ide_lock, flags); } /** @@ -291,7 +286,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) { ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; struct request *rq = hwgroup->rq; - unsigned long flags; if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *task = (ide_task_t *)rq->special; @@ -323,11 +317,9 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) rq->errors = err; - spin_lock_irqsave(&ide_lock, flags); - if (unlikely(__blk_end_request(rq, (rq->errors ? -EIO : 0), - blk_rq_bytes(rq)))) + if (unlikely(blk_end_request(rq, (rq->errors ? -EIO : 0), + blk_rq_bytes(rq)))) BUG(); - spin_unlock_irqrestore(&ide_lock, flags); } EXPORT_SYMBOL(ide_end_drive_cmd); -- cgit From 6ea52226ca131a99bb619bd56fbeee566ea5a966 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:31 +0100 Subject: ide: use queue lock instead of ide_lock when possible This is just a preparation for future changes and there should be no functional changes caused by this patch since ide_lock is currently also used as queue lock. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 14 ++++++++------ drivers/ide/ide-io.c | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ac607bbde45..692fd4570df 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -424,16 +424,17 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) if (time_after(jiffies, info->write_timeout)) do_end_request = 1; else { + struct request_queue *q = drive->queue; unsigned long flags; /* * take a breather relying on the unplug * timer to kick us again */ - spin_lock_irqsave(&ide_lock, flags); - blk_plug_device(drive->queue); - spin_unlock_irqrestore(&ide_lock, - flags); + spin_lock_irqsave(q->queue_lock, flags); + blk_plug_device(q); + spin_unlock_irqrestore(q->queue_lock, flags); + return 1; } } @@ -502,11 +503,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) end_request: if (stat & ATA_ERR) { + struct request_queue *q = drive->queue; unsigned long flags; - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(q->queue_lock, flags); blkdev_dequeue_request(rq); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(q->queue_lock, flags); hwgroup->rq = NULL; diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 4a6576f6146..02059e96e6c 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -247,20 +247,21 @@ EXPORT_SYMBOL_GPL(ide_end_dequeued_request); */ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) { + struct request_queue *q = drive->queue; unsigned long flags; #ifdef DEBUG_PM printk("%s: completing PM request, %s\n", drive->name, blk_pm_suspend_request(rq) ? "suspend" : "resume"); #endif - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(q->queue_lock, flags); if (blk_pm_suspend_request(rq)) { - blk_stop_queue(drive->queue); + blk_stop_queue(q); } else { drive->dev_flags &= ~IDE_DFLAG_BLOCKED; - blk_start_queue(drive->queue); + blk_start_queue(q); } - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(q->queue_lock, flags); drive->hwif->hwgroup->rq = NULL; @@ -1469,16 +1470,16 @@ out: void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) { ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; + struct request_queue *q = drive->queue; unsigned long flags; hwgroup->rq = NULL; - spin_lock_irqsave(&ide_lock, flags); - __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); - blk_start_queueing(drive->queue); - spin_unlock_irqrestore(&ide_lock, flags); + spin_lock_irqsave(q->queue_lock, flags); + __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); + blk_start_queueing(q); + spin_unlock_irqrestore(q->queue_lock, flags); } - EXPORT_SYMBOL(ide_do_drive_cmd); void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma) -- cgit From 2a2ca6a96194c4744a2adeefbc09ce881f3c5abe Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:31 +0100 Subject: ide: replace the global ide_lock spinlock by per-hwgroup spinlocks (v2) Now that (almost) all host drivers have been fixed not to abuse ide_lock and core code usage of ide_lock has been sanitized we may safely replace ide_lock by per-hwgroup locks. This patch is partially based on earlier patch from Ravikiran G Thirumalai. While at it: - don't use deprecated HWIF() and HWGROUP() macros - update locking documentation in ide.h v2: Add missing spin_lock_init(&hwgroup->lock). (Noticed by Elias Oltmanns) Cc: Vaibhav V. Nivargi Cc: Alok N. Kataria Cc: Shai Fultheim Signed-off-by: Ravikiran Thirumalai Cc: Elias Oltmanns Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 33 ++++++++++++++++----------------- drivers/ide/ide-iops.c | 48 +++++++++++++++++++++++------------------------- drivers/ide/ide-park.c | 16 ++++++++-------- drivers/ide/ide-probe.c | 26 +++++++++++++++----------- drivers/ide/ide.c | 8 +++----- drivers/ide/umc8672.c | 11 +++++++---- 6 files changed, 72 insertions(+), 70 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 02059e96e6c..72d0d702d5d 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -907,7 +907,7 @@ repeat: /* * Issue a new request to a drive from hwgroup - * Caller must have already done spin_lock_irqsave(&ide_lock, ..); + * Caller must have already done spin_lock_irqsave(&hwgroup->lock, ..); * * A hwgroup is a serialized group of IDE interfaces. Usually there is * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) @@ -919,7 +919,7 @@ repeat: * possibly along with many other devices. This is especially common in * PCI-based systems with off-board IDE controller cards. * - * The IDE driver uses the single global ide_lock spinlock to protect + * The IDE driver uses a per-hwgroup spinlock to protect * access to the request queues, and to protect the hwgroup->busy flag. * * The first thread into the driver for a particular hwgroup sets the @@ -935,7 +935,7 @@ repeat: * will start the next request from the queue. If no more work remains, * the driver will clear the hwgroup->busy flag and exit. * - * The ide_lock (spinlock) is used to protect all access to the + * The per-hwgroup spinlock is used to protect all access to the * hwgroup->busy flag, but is otherwise not needed for most processing in * the driver. This makes the driver much more friendlier to shared IRQs * than previous designs, while remaining 100% (?) SMP safe and capable. @@ -948,7 +948,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ide_startstop_t startstop; int loops = 0; - /* caller must own ide_lock */ + /* caller must own hwgroup->lock */ BUG_ON(!irqs_disabled()); while (!hwgroup->busy) { @@ -1070,11 +1070,11 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) */ if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) disable_irq_nosync(hwif->irq); - spin_unlock(&ide_lock); + spin_unlock(&hwgroup->lock); local_irq_enable_in_hardirq(); /* allow other IRQs while we start this request */ startstop = start_request(drive, rq); - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) enable_irq(hwif->irq); if (startstop == ide_stopped) @@ -1172,7 +1172,7 @@ void ide_timer_expiry (unsigned long data) unsigned long flags; unsigned long wait = -1; - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&hwgroup->lock, flags); if (((handler = hwgroup->handler) == NULL) || (hwgroup->req_gen != hwgroup->req_gen_timer)) { @@ -1205,7 +1205,7 @@ void ide_timer_expiry (unsigned long data) hwgroup->timer.expires = jiffies + wait; hwgroup->req_gen_timer = hwgroup->req_gen; add_timer(&hwgroup->timer); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); return; } } @@ -1215,7 +1215,7 @@ void ide_timer_expiry (unsigned long data) * the handler() function, which means we need to * globally mask the specific IRQ: */ - spin_unlock(&ide_lock); + spin_unlock(&hwgroup->lock); hwif = HWIF(drive); /* disable_irq_nosync ?? */ disable_irq(hwif->irq); @@ -1239,14 +1239,14 @@ void ide_timer_expiry (unsigned long data) hwif->tp_ops->read_status(hwif)); } drive->service_time = jiffies - drive->service_start; - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); enable_irq(hwif->irq); if (startstop == ide_stopped) hwgroup->busy = 0; } } ide_do_request(hwgroup, IDE_NO_IRQ); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); } /** @@ -1339,14 +1339,13 @@ irqreturn_t ide_intr (int irq, void *dev_id) { unsigned long flags; ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; - ide_hwif_t *hwif; + ide_hwif_t *hwif = hwgroup->hwif; ide_drive_t *drive; ide_handler_t *handler; ide_startstop_t startstop; irqreturn_t irq_ret = IRQ_NONE; - spin_lock_irqsave(&ide_lock, flags); - hwif = hwgroup->hwif; + spin_lock_irqsave(&hwgroup->lock, flags); if (!ide_ack_intr(hwif)) goto out; @@ -1416,7 +1415,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) hwgroup->handler = NULL; hwgroup->req_gen++; del_timer(&hwgroup->timer); - spin_unlock(&ide_lock); + spin_unlock(&hwgroup->lock); if (hwif->port_ops && hwif->port_ops->clear_irq) hwif->port_ops->clear_irq(drive); @@ -1427,7 +1426,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) /* service this interrupt, may set handler for next interrupt */ startstop = handler(drive); - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); /* * Note that handler() may have set things up for another * interrupt to occur soon, but it cannot happen until @@ -1448,7 +1447,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) out_handled: irq_ret = IRQ_HANDLED; out: - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); return irq_ret; } diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index c41c3b9b6f0..ad8bd653928 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -835,10 +835,12 @@ static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry) { + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; unsigned long flags; - spin_lock_irqsave(&ide_lock, flags); + + spin_lock_irqsave(&hwgroup->lock, flags); __ide_set_handler(drive, handler, timeout, expiry); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); } EXPORT_SYMBOL(ide_set_handler); @@ -860,10 +862,11 @@ EXPORT_SYMBOL(ide_set_handler); void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, unsigned timeout, ide_expiry_t *expiry) { + ide_hwif_t *hwif = drive->hwif; + ide_hwgroup_t *hwgroup = hwif->hwgroup; unsigned long flags; - ide_hwif_t *hwif = HWIF(drive); - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&hwgroup->lock, flags); __ide_set_handler(drive, handler, timeout, expiry); hwif->tp_ops->exec_command(hwif, cmd); /* @@ -873,19 +876,20 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, * FIXME: we could skip this delay with care on non shared devices */ ndelay(400); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); } EXPORT_SYMBOL(ide_execute_command); void ide_execute_pkt_cmd(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; + ide_hwgroup_t *hwgroup = hwif->hwgroup; unsigned long flags; - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&hwgroup->lock, flags); hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET); ndelay(400); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); } EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); @@ -1076,22 +1080,16 @@ static void pre_reset(ide_drive_t *drive) */ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) { - unsigned int unit; - unsigned long flags, timeout; - ide_hwif_t *hwif; - ide_hwgroup_t *hwgroup; - struct ide_io_ports *io_ports; - const struct ide_tp_ops *tp_ops; + ide_hwif_t *hwif = drive->hwif; + ide_hwgroup_t *hwgroup = hwif->hwgroup; + struct ide_io_ports *io_ports = &hwif->io_ports; + const struct ide_tp_ops *tp_ops = hwif->tp_ops; const struct ide_port_ops *port_ops; + unsigned long flags, timeout; + unsigned int unit; DEFINE_WAIT(wait); - spin_lock_irqsave(&ide_lock, flags); - hwif = HWIF(drive); - hwgroup = HWGROUP(drive); - - io_ports = &hwif->io_ports; - - tp_ops = hwif->tp_ops; + spin_lock_irqsave(&hwgroup->lock, flags); /* We must not reset with running handlers */ BUG_ON(hwgroup->handler != NULL); @@ -1106,7 +1104,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; hwgroup->polling = 1; __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); return ide_started; } @@ -1129,9 +1127,9 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) if (time_before_eq(timeout, now)) break; - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); timeout = schedule_timeout_uninterruptible(timeout - now); - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&hwgroup->lock, flags); } while (timeout); finish_wait(&ide_park_wq, &wait); @@ -1143,7 +1141,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) pre_reset(&hwif->drives[unit]); if (io_ports->ctl_addr == 0) { - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); ide_complete_drive_reset(drive, -ENXIO); return ide_stopped; } @@ -1179,7 +1177,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) if (port_ops && port_ops->resetproc) port_ops->resetproc(drive); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); return ide_started; } diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 03b00e57e93..63d01c55f86 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c @@ -7,17 +7,16 @@ DECLARE_WAIT_QUEUE_HEAD(ide_park_wq); static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) { + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; struct request_queue *q = drive->queue; struct request *rq; int rc; timeout += jiffies; - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); if (drive->dev_flags & IDE_DFLAG_PARKED) { - ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; - int reset_timer; + int reset_timer = time_before(timeout, drive->sleep); - reset_timer = time_before(timeout, drive->sleep); drive->sleep = timeout; wake_up_all(&ide_park_wq); if (reset_timer && hwgroup->sleeping && @@ -26,10 +25,10 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) hwgroup->busy = 0; blk_start_queueing(q); } - spin_unlock_irq(&ide_lock); + spin_unlock_irq(&hwgroup->lock); return; } - spin_unlock_irq(&ide_lock); + spin_unlock_irq(&hwgroup->lock); rq = blk_get_request(q, READ, __GFP_WAIT); rq->cmd[0] = REQ_PARK_HEADS; @@ -62,20 +61,21 @@ ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, char *buf) { ide_drive_t *drive = to_ide_device(dev); + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; unsigned long now; unsigned int msecs; if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD) return -EOPNOTSUPP; - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); now = jiffies; if (drive->dev_flags & IDE_DFLAG_PARKED && time_after(drive->sleep, now)) msecs = jiffies_to_msecs(drive->sleep - now); else msecs = 0; - spin_unlock_irq(&ide_lock); + spin_unlock_irq(&hwgroup->lock); return snprintf(buf, 20, "%u\n", msecs); } diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index c55bdbd2231..504bc9480e9 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -906,7 +906,8 @@ static int ide_init_queue(ide_drive_t *drive) * do not. */ - q = blk_init_queue_node(do_ide_request, &ide_lock, hwif_to_node(hwif)); + q = blk_init_queue_node(do_ide_request, &hwif->hwgroup->lock, + hwif_to_node(hwif)); if (!q) return 1; @@ -947,7 +948,7 @@ static void ide_add_drive_to_hwgroup(ide_drive_t *drive) { ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); if (!hwgroup->drive) { /* first drive for hwgroup. */ drive->next = drive; @@ -957,7 +958,7 @@ static void ide_add_drive_to_hwgroup(ide_drive_t *drive) drive->next = hwgroup->drive->next; hwgroup->drive->next = drive; } - spin_unlock_irq(&ide_lock); + spin_unlock_irq(&hwgroup->lock); } /* @@ -1002,7 +1003,7 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) ide_ports[hwif->index] = NULL; - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); /* * Remove us from the hwgroup, and free * the hwgroup if we were the only member @@ -1030,7 +1031,7 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) } BUG_ON(hwgroup->hwif == hwif); } - spin_unlock_irq(&ide_lock); + spin_unlock_irq(&hwgroup->lock); } /* @@ -1092,17 +1093,19 @@ static int init_irq (ide_hwif_t *hwif) * linked list, the first entry is the hwif that owns * hwgroup->handler - do not change that. */ - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); hwif->next = hwgroup->hwif->next; hwgroup->hwif->next = hwif; BUG_ON(hwif->next == hwif); - spin_unlock_irq(&ide_lock); + spin_unlock_irq(&hwgroup->lock); } else { hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO, hwif_to_node(hwif)); if (hwgroup == NULL) goto out_up; + spin_lock_init(&hwgroup->lock); + hwif->hwgroup = hwgroup; hwgroup->hwif = hwif->next = hwif; @@ -1263,20 +1266,21 @@ static void ide_remove_drive_from_hwgroup(ide_drive_t *drive) static void drive_release_dev (struct device *dev) { ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; ide_proc_unregister_device(drive); - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); ide_remove_drive_from_hwgroup(drive); kfree(drive->id); drive->id = NULL; drive->dev_flags &= ~IDE_DFLAG_PRESENT; /* Messed up locking ... */ - spin_unlock_irq(&ide_lock); + spin_unlock_irq(&hwgroup->lock); blk_cleanup_queue(drive->queue); - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); drive->queue = NULL; - spin_unlock_irq(&ide_lock); + spin_unlock_irq(&hwgroup->lock); complete(&drive->gendev_rel_comp); } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index bca6877ee6a..41d04205354 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -74,9 +74,6 @@ static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, DEFINE_MUTEX(ide_cfg_mtx); -__cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); -EXPORT_SYMBOL(ide_lock); - static void ide_port_init_devices_data(ide_hwif_t *); /* @@ -333,6 +330,7 @@ static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) static int set_pio_mode(ide_drive_t *drive, int arg) { ide_hwif_t *hwif = drive->hwif; + ide_hwgroup_t *hwgroup = hwif->hwgroup; const struct ide_port_ops *port_ops = hwif->port_ops; if (arg < 0 || arg > 255) @@ -347,9 +345,9 @@ static int set_pio_mode(ide_drive_t *drive, int arg) unsigned long flags; /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */ - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&hwgroup->lock, flags); port_ops->set_pio_mode(drive, arg); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); } else port_ops->set_pio_mode(drive, arg); } else { diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c index 1da076e0c91..e29978cf619 100644 --- a/drivers/ide/umc8672.c +++ b/drivers/ide/umc8672.c @@ -107,18 +107,21 @@ static void umc_set_speeds(u8 speeds[]) static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = drive->hwif; - unsigned long flags; + ide_hwgroup_t *mate_hwgroup = hwif->mate ? hwif->mate->hwgroup : NULL; + unsigned long uninitialized_var(flags); printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", drive->name, pio, pio_to_umc[pio]); - spin_lock_irqsave(&ide_lock, flags); - if (hwif->mate && hwif->mate->hwgroup->handler) { + if (mate_hwgroup) + spin_lock_irqsave(&mate_hwgroup->lock, flags); + if (mate_hwgroup && mate_hwgroup->handler) { printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); } else { current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; umc_set_speeds(current_speeds); } - spin_unlock_irqrestore(&ide_lock, flags); + if (mate_hwgroup) + spin_unlock_irqrestore(&mate_hwgroup->lock, flags); } static const struct ide_port_ops umc8672_port_ops = { -- cgit From 08cd1dca00f7c84c8b30c2726e078529d4ebc93f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:32 +0100 Subject: ide: cleanup ide_do_request() Both choose_drive() and PM handling code make sure that the queue is unplugged so no need to check it again. Cc: Elias Oltmanns Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 72d0d702d5d..e41488e1ed4 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1016,11 +1016,6 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); drive->service_start = jiffies; - if (blk_queue_plugged(drive->queue)) { - printk(KERN_ERR "ide: huh? queue was plugged!\n"); - break; - } - /* * we know that the queue isn't empty, but this can happen * if the q->prep_rq_fn() decides to kill a request -- cgit From 27c01c2db05c3cf8824975e50403cd4fd9356dca Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:32 +0100 Subject: ide-cd: remove obsolete seek optimization It doesn't make much sense nowadays and is problematic on some drives. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 89 ++++------------------------------------------------ drivers/ide/ide-cd.h | 2 -- 2 files changed, 6 insertions(+), 85 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 692fd4570df..ea35e94d098 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -774,52 +774,6 @@ static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive) return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); } -#define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */ -#define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP) /* 100 ms */ -#define IDECD_SEEK_TIMEOUT (2 * WAIT_CMD) /* 20 sec */ - -static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) -{ - struct cdrom_info *info = drive->driver_data; - int stat; - static int retry = 10; - - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - - if (cdrom_decode_status(drive, 0, &stat)) - return ide_stopped; - - drive->atapi_flags |= IDE_AFLAG_SEEKING; - - if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) { - if (--retry == 0) - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; - } - return ide_stopped; -} - -static void ide_cd_prepare_seek_request(ide_drive_t *drive, struct request *rq) -{ - sector_t frame = rq->sector; - - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); - - sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS); - - memset(rq->cmd, 0, BLK_MAX_CDB); - rq->cmd[0] = GPCMD_SEEK; - put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]); - - rq->timeout = ATAPI_WAIT_PC; -} - -static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) -{ - struct request *rq = drive->hwif->hwgroup->rq; - - return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr); -} - /* * Fix up a possibly partially-processed request so that we can start it over * entirely, or even put it back on the request queue. @@ -1260,7 +1214,6 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { - struct cdrom_info *info = drive->driver_data; ide_handler_t *fn; int xferlen; @@ -1270,44 +1223,14 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, (unsigned long long)block); if (blk_fs_request(rq)) { - if (drive->atapi_flags & IDE_AFLAG_SEEKING) { - ide_hwif_t *hwif = drive->hwif; - unsigned long elapsed = jiffies - info->start_seek; - int stat = hwif->tp_ops->read_status(hwif); - - if ((stat & ATA_DSC) != ATA_DSC) { - if (elapsed < IDECD_SEEK_TIMEOUT) { - ide_stall_queue(drive, - IDECD_SEEK_TIMER); - return ide_stopped; - } - printk(KERN_ERR PFX "%s: DSC timeout\n", - drive->name); - } - drive->atapi_flags &= ~IDE_AFLAG_SEEKING; - } - if (rq_data_dir(rq) == READ && - IDE_LARGE_SEEK(info->last_block, block, - IDECD_SEEK_THRESHOLD) && - (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP)) { - xferlen = 0; - fn = cdrom_start_seek_continuation; - - drive->dma = 0; - info->start_seek = jiffies; - - ide_cd_prepare_seek_request(drive, rq); - } else { - xferlen = 32768; - fn = cdrom_start_rw_cont; + xferlen = 32768; + fn = cdrom_start_rw_cont; - if (cdrom_start_rw(drive, rq) == ide_stopped) - return ide_stopped; + if (cdrom_start_rw(drive, rq) == ide_stopped) + return ide_stopped; - if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped) - return ide_stopped; - } - info->last_block = block; + if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped) + return ide_stopped; } else if (blk_sense_request(rq) || blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { xferlen = rq->data_len; diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 5882b9a9ea8..d5ce3362dbd 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -88,8 +88,6 @@ struct cdrom_info { struct request_sense sense_data; struct request request_sense_request; - unsigned long last_block; - unsigned long start_seek; u8 max_speed; /* Max speed of the drive. */ u8 current_speed; /* Current speed of the drive. */ -- cgit From 02fb5683c98b0ce9ff75d890ebccd8e520d0e7a9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:32 +0100 Subject: ali14xx: doesn't use shared IRQs init_irq() shouldn't use IRQF_SHARED for ali14xx IDE IRQ handler. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 504bc9480e9..b0f9ededfad 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1125,8 +1125,7 @@ static int init_irq (ide_hwif_t *hwif) sa = IRQF_SHARED; #endif /* __mc68000__ */ - if (hwif->chipset == ide_pci || hwif->chipset == ide_cmd646 || - hwif->chipset == ide_ali14xx) + if (hwif->chipset == ide_pci || hwif->chipset == ide_cmd646) sa = IRQF_SHARED; if (io_ports->ctl_addr) -- cgit From 6b5cde3629701258004b94cde75dd1089b556b02 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:32 +0100 Subject: cmd64x: set IDE_HFLAG_SERIALIZE explictly for CMD646 * Set IDE_HFLAG_SERIALIZE explictly for CMD646. * Remove no longer needed ide_cmd646 chipset type (which has a nice side-effect of fixing handling of unexpected IRQs). Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/cmd64x.c | 4 ++-- drivers/ide/ide-probe.c | 2 +- drivers/ide/ide-proc.c | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 935385c77e0..3623bf013bc 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -424,10 +424,10 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { .name = DRV_NAME, .init_chipset = init_chipset_cmd64x, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, - .chipset = ide_cmd646, .port_ops = &cmd64x_port_ops, .dma_ops = &cmd648_dma_ops, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH, + .host_flags = IDE_HFLAG_SERIALIZE | + IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA2, diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index b0f9ededfad..a0eb72e2a02 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1125,7 +1125,7 @@ static int init_irq (ide_hwif_t *hwif) sa = IRQF_SHARED; #endif /* __mc68000__ */ - if (hwif->chipset == ide_pci || hwif->chipset == ide_cmd646) + if (hwif->chipset == ide_pci) sa = IRQF_SHARED; if (io_ports->ctl_addr) diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index dd899e1f384..e41669eec2c 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -48,7 +48,6 @@ static int proc_ide_read_imodel case ide_ht6560b: name = "ht6560b"; break; case ide_rz1000: name = "rz1000"; break; case ide_trm290: name = "trm290"; break; - case ide_cmd646: name = "cmd646"; break; case ide_cy82c693: name = "cy82c693"; break; case ide_4drives: name = "4drives"; break; case ide_pmac: name = "mac-io"; break; -- cgit From a4cd1a344818b4aa7149b851dc61f0447dc398bc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:33 +0100 Subject: gayle: set IDE_HFLAG_SERIALIZE explictly If IDE doubler is used ports need to be serialized. Currently init_irq() handles it fine but lets also set IDE_HFLAG_SERIALIZE host flag explicitly in preparation for future changes. Also convert the driver to use struct ide_port_info while at it. Cc: Geert Uytterhoeven Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/gayle.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/ide') diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c index 69150688656..59bd0be9dcb 100644 --- a/drivers/ide/gayle.c +++ b/drivers/ide/gayle.c @@ -117,6 +117,10 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base, hw->chipset = ide_generic; } +static const struct ide_port_info gayle_port_info = { + .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA, +}; + /* * Probe for a Gayle IDE interface (and optionally for an IDE doubler) */ @@ -178,7 +182,7 @@ found: hws[i] = &hw[i]; } - rc = ide_host_add(NULL, hws, NULL); + rc = ide_host_add(&gayle_port_info, hws, NULL); if (rc) release_mem_region(res_start, res_n); -- cgit From 46aa7af1d6bf46d0973dc9e8f13275f2c001d3dd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:33 +0100 Subject: ide: fix ->quirk_list checking in ide_do_request() Fix nIEN quirk check to also omit quirky devices using pdc202xx_{new,old} host drivers for which ->quirk_list == 2. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index e41488e1ed4..ca51460af75 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1008,7 +1008,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) * set nIEN for previous hwif, drives in the * quirk_list may not like intr setups/cleanups */ - if (drive->quirk_list != 1) + if (drive->quirk_list == 0) hwif->tp_ops->set_irq(hwif, 0); } hwgroup->hwif = hwif; -- cgit From f58c1ab8deebc2360cef998f169a6727c288210f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:33 +0100 Subject: ide: always set nIEN on idle devices * Set nIEN for previous port/device in ide_do_request() also if port uses a non-shared IRQ. * Remove no longer needed ide_hwif_t.sharing_irq. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 2 +- drivers/ide/ide-probe.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ca51460af75..f776bd47501 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1003,7 +1003,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) } again: hwif = HWIF(drive); - if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif) { + if (hwif != hwgroup->hwif) { /* * set nIEN for previous hwif, drives in the * quirk_list may not like intr setups/cleanups diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index a0eb72e2a02..81f61e8ea97 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1060,7 +1060,6 @@ static int init_irq (ide_hwif_t *hwif) if (h && h->hwgroup) { /* scan only initialized ports */ if (hwif->irq == h->irq) { - hwif->sharing_irq = h->sharing_irq = 1; if (hwif->chipset != ide_pci || h->chipset != ide_pci) { save_match(hwif, h, &match); @@ -1152,8 +1151,7 @@ static int init_irq (ide_hwif_t *hwif) io_ports->data_addr, hwif->irq); #endif /* __mc68000__ */ if (match) - printk(KERN_CONT " (%sed with %s)", - hwif->sharing_irq ? "shar" : "serializ", match->name); + printk(KERN_CONT " (serialized with %s)", match->name); printk(KERN_CONT "\n"); mutex_unlock(&ide_cfg_mtx); -- cgit From 7f1ac8c4b9dadc55ec656b368f5f470f2cbe3083 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:33 +0100 Subject: rz1000: apply chipset quirks early (v2) * Use pci_name(dev) instead of hwif->name in init_hwif_rz1000(). * init_hwif_rz1000() -> rz1000_init_chipset(). Update rz1000_init_one() to use rz1000_init_chipset() and add now required rz1000_remove(). * Remove superfluous ide_rz1000 chipset type. v2: * unsigned int rz1000_init_chipset() -> int rz1000_disable_readahead() per Sergei's suggestion. Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-proc.c | 1 - drivers/ide/rz1000.c | 36 +++++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 12 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index e41669eec2c..c2e6b8927bd 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -46,7 +46,6 @@ static int proc_ide_read_imodel case ide_qd65xx: name = "qd65xx"; break; case ide_umc8672: name = "umc8672"; break; case ide_ht6560b: name = "ht6560b"; break; - case ide_rz1000: name = "rz1000"; break; case ide_trm290: name = "trm290"; break; case ide_cy82c693: name = "cy82c693"; break; case ide_4drives: name = "4drives"; break; diff --git a/drivers/ide/rz1000.c b/drivers/ide/rz1000.c index 7daf0135cba..a6414a884eb 100644 --- a/drivers/ide/rz1000.c +++ b/drivers/ide/rz1000.c @@ -22,34 +22,48 @@ #define DRV_NAME "rz1000" -static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif) +static int __devinit rz1000_disable_readahead(struct pci_dev *dev) { - struct pci_dev *dev = to_pci_dev(hwif->dev); u16 reg; if (!pci_read_config_word (dev, 0x40, ®) && !pci_write_config_word(dev, 0x40, reg & 0xdfff)) { printk(KERN_INFO "%s: disabled chipset read-ahead " - "(buggy RZ1000/RZ1001)\n", hwif->name); + "(buggy RZ1000/RZ1001)\n", pci_name(dev)); + return 0; } else { - if (hwif->mate) - hwif->mate->serialized = hwif->serialized = 1; - hwif->host_flags |= IDE_HFLAG_NO_UNMASK_IRQS; printk(KERN_INFO "%s: serialized, disabled unmasking " - "(buggy RZ1000/RZ1001)\n", hwif->name); + "(buggy RZ1000/RZ1001)\n", pci_name(dev)); + return 1; } } static const struct ide_port_info rz1000_chipset __devinitdata = { .name = DRV_NAME, - .init_hwif = init_hwif_rz1000, - .chipset = ide_rz1000, .host_flags = IDE_HFLAG_NO_DMA, }; static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - return ide_pci_init_one(dev, &rz1000_chipset, NULL); + struct ide_port_info d = rz1000_chipset; + int rc; + + rc = pci_enable_device(dev); + if (rc) + return rc; + + if (rz1000_disable_readahead(dev)) { + d.host_flags |= IDE_HFLAG_SERIALIZE; + d.host_flags |= IDE_HFLAG_NO_UNMASK_IRQS; + } + + return ide_pci_init_one(dev, &d, NULL); +} + +static void rz1000_remove(struct pci_dev *dev) +{ + ide_pci_remove(dev); + pci_disable_device(dev); } static const struct pci_device_id rz1000_pci_tbl[] = { @@ -63,7 +77,7 @@ static struct pci_driver rz1000_pci_driver = { .name = "RZ1000_IDE", .id_table = rz1000_pci_tbl, .probe = rz1000_init_one, - .remove = ide_pci_remove, + .remove = rz1000_remove, }; static int __init rz1000_ide_init(void) -- cgit From 6b4924962c49655494d2c8e9d3faab0e349a3062 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:34 +0100 Subject: ide: add ->max_sectors field to struct ide_port_info * Add ->max_sectors field to struct ide_port_info to allow host drivers to specify value used for hwif->rqsize (if smaller than the default). * Convert pdc202xx_old to use ->max_sectors and remove no longer needed IDE_HFLAG_RQSIZE_256 flag. There should be no functional changes caused by this patch. Acked-by: Sergei Shtyltov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 4 ++-- drivers/ide/pdc202xx_old.c | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 81f61e8ea97..f76c22c4508 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1442,8 +1442,8 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, hwif->mate->serialized = hwif->serialized = 1; } - if (d->host_flags & IDE_HFLAG_RQSIZE_256) - hwif->rqsize = 256; + if (d->max_sectors) + hwif->rqsize = d->max_sectors; /* call chipset specific routine for each enabled port */ if (d->init_hwif) diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index 799557c25ee..624e62e5cc9 100644 --- a/drivers/ide/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c @@ -350,16 +350,17 @@ static const struct ide_dma_ops pdc2026x_dma_ops = { .dma_timeout = pdc202xx_dma_timeout, }; -#define DECLARE_PDC2026X_DEV(udma, extra_flags) \ +#define DECLARE_PDC2026X_DEV(udma, sectors) \ { \ .name = DRV_NAME, \ .init_chipset = init_chipset_pdc202xx, \ .port_ops = &pdc2026x_port_ops, \ .dma_ops = &pdc2026x_dma_ops, \ - .host_flags = IDE_HFLAGS_PDC202XX | extra_flags, \ + .host_flags = IDE_HFLAGS_PDC202XX, \ .pio_mask = ATA_PIO4, \ .mwdma_mask = ATA_MWDMA2, \ .udma_mask = udma, \ + .max_sectors = sectors, \ } static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = { @@ -376,8 +377,8 @@ static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = { /* 1: PDC2026{2,3} */ DECLARE_PDC2026X_DEV(ATA_UDMA4, 0), - /* 2: PDC2026{5,7} */ - DECLARE_PDC2026X_DEV(ATA_UDMA5, IDE_HFLAG_RQSIZE_256), + /* 2: PDC2026{5,7}: UDMA5, limit LBA48 requests to 256 sectors */ + DECLARE_PDC2026X_DEV(ATA_UDMA5, 256), }; /** -- cgit From 1f66019bdf902cb59adf959e462bcd3f4c01f683 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:34 +0100 Subject: trm290: add IDE_HFLAG_TRM290 host flag * Add IDE_HFLAG_TRM290 host flag and use it in ide_build_dmatable(). * Remove no longer needed ide_trm290 chipset type. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma-sff.c | 2 +- drivers/ide/ide-proc.c | 1 - drivers/ide/trm290.c | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c index cac431f0df1..1f2a5f56f81 100644 --- a/drivers/ide/ide-dma-sff.c +++ b/drivers/ide/ide-dma-sff.c @@ -98,10 +98,10 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq) { ide_hwif_t *hwif = drive->hwif; __le32 *table = (__le32 *)hwif->dmatable_cpu; - unsigned int is_trm290 = (hwif->chipset == ide_trm290) ? 1 : 0; unsigned int count = 0; int i; struct scatterlist *sg; + u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290); hwif->sg_nents = ide_build_sglist(drive, rq); if (hwif->sg_nents == 0) diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index c2e6b8927bd..066d2317545 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -46,7 +46,6 @@ static int proc_ide_read_imodel case ide_qd65xx: name = "qd65xx"; break; case ide_umc8672: name = "umc8672"; break; case ide_ht6560b: name = "ht6560b"; break; - case ide_trm290: name = "trm290"; break; case ide_cy82c693: name = "cy82c693"; break; case ide_4drives: name = "4drives"; break; case ide_pmac: name = "mac-io"; break; diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c index 75ea6152656..2a5ea90cf8b 100644 --- a/drivers/ide/trm290.c +++ b/drivers/ide/trm290.c @@ -328,10 +328,10 @@ static struct ide_dma_ops trm290_dma_ops = { static const struct ide_port_info trm290_chipset __devinitdata = { .name = DRV_NAME, .init_hwif = init_hwif_trm290, - .chipset = ide_trm290, .port_ops = &trm290_port_ops, .dma_ops = &trm290_dma_ops, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | + .host_flags = IDE_HFLAG_TRM290 | + IDE_HFLAG_NO_ATAPI_DMA | #if 0 /* play it safe for now */ IDE_HFLAG_TRUST_BIOS_FOR_DMA | #endif -- cgit From b7876a6fb6e9bf6cbcf7b40cf034aa4138d7978f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:34 +0100 Subject: cy82c693: remove superfluous ide_cy82c693 chipset type Since CY82C693 doesn't require serialization we may as well use the default ide_pci chipset type. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/cy82c693.c | 1 - drivers/ide/ide-proc.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 5297f07d293..d37baf8ecc5 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -292,7 +292,6 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = { .name = DRV_NAME, .init_iops = init_iops_cy82c693, .port_ops = &cy82c693_port_ops, - .chipset = ide_cy82c693, .host_flags = IDE_HFLAG_SINGLE, .pio_mask = ATA_PIO4, .swdma_mask = ATA_SWDMA2, diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 066d2317545..a14e2938e4f 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -46,7 +46,6 @@ static int proc_ide_read_imodel case ide_qd65xx: name = "qd65xx"; break; case ide_umc8672: name = "umc8672"; break; case ide_ht6560b: name = "ht6560b"; break; - case ide_cy82c693: name = "cy82c693"; break; case ide_4drives: name = "4drives"; break; case ide_pmac: name = "mac-io"; break; case ide_au1xxx: name = "au1xxx"; break; -- cgit From 702c026be87ef8374ae58122969a4b0b081ce6f2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:36 +0100 Subject: ide: rework handling of serialized ports (v2) * hpt366: set IDE_HFLAG_SERIALIZE in ->host_flags if needed in init_hwif_hpt366(). Remove HPT_SERIALIZE_IO while at it. * Set IDE_HFLAG_SERIALIZE in ->host_flags if needed in ide_init_port(). * Convert init_irq() to use IDE_HFLAG_SERIALIZE together with hwif->host to find out ports which need to be serialized. * Remove no longer needed save_match() and ide_hwif_t.serialized. v2: * Set host's ->host_flags field instead of port's copy. This patch should fix the incorrect grouping of port(s) from host(s) that need serialization with port(s) that happen to use the same IRQ(s) but are from the host(s) that don't need it. Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/hpt366.c | 8 +------- drivers/ide/ide-probe.c | 50 +++++-------------------------------------------- 2 files changed, 6 insertions(+), 52 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index f5afd46ed51..b18e10d99d2 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c @@ -135,7 +135,6 @@ /* various tuning parameters */ #define HPT_RESET_STATE_ENGINE #undef HPT_DELAY_INTERRUPT -#define HPT_SERIALIZE_IO 0 static const char *quirk_drives[] = { "QUANTUM FIREBALLlct08 08", @@ -1288,7 +1287,6 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) { struct hpt_info *info = hpt3xx_get_info(hwif->dev); - int serialize = HPT_SERIALIZE_IO; u8 chip_type = info->chip_type; /* Cache the channel's MISC. control registers' offset */ @@ -1305,13 +1303,9 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) * Clock is shared between the channels, * so we'll have to serialize them... :-( */ - serialize = 1; + hwif->host->host_flags |= IDE_HFLAG_SERIALIZE; hwif->rw_disk = &hpt3xxn_rw_disk; } - - /* Serialize access to this device if needed */ - if (serialize && hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; } static int __devinit init_dma_hpt366(ide_hwif_t *hwif, diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index f76c22c4508..c1cd1af2646 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -863,31 +863,6 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) } } -/* - * save_match() is used to simplify logic in init_irq() below. - * - * A loophole here is that we may not know about a particular - * hwif's irq until after that hwif is actually probed/initialized.. - * This could be a problem for the case where an hwif is on a - * dual interface that requires serialization (eg. cmd640) and another - * hwif using one of the same irqs is initialized beforehand. - * - * This routine detects and reports such situations, but does not fix them. - */ -static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match) -{ - ide_hwif_t *m = *match; - - if (m && m->hwgroup && m->hwgroup != new->hwgroup) { - if (!new->hwgroup) - return; - printk(KERN_WARNING "%s: potential IRQ problem with %s and %s\n", - hwif->name, new->name, m->name); - } - if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */ - *match = new; -} - /* * init request queue */ @@ -1052,26 +1027,13 @@ static int init_irq (ide_hwif_t *hwif) mutex_lock(&ide_cfg_mtx); hwif->hwgroup = NULL; - /* - * Group up with any other hwifs that share our irq(s). - */ for (index = 0; index < MAX_HWIFS; index++) { ide_hwif_t *h = ide_ports[index]; if (h && h->hwgroup) { /* scan only initialized ports */ - if (hwif->irq == h->irq) { - if (hwif->chipset != ide_pci || - h->chipset != ide_pci) { - save_match(hwif, h, &match); - } - } - if (hwif->serialized) { - if (hwif->mate && hwif->mate->irq == h->irq) - save_match(hwif, h, &match); - } - if (h->serialized) { - if (h->mate && hwif->irq == h->mate->irq) - save_match(hwif, h, &match); + if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) { + if (hwif->host == h->host) + match = h; } } } @@ -1437,10 +1399,8 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, } if ((d->host_flags & IDE_HFLAG_SERIALIZE) || - ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) { - if (hwif->mate) - hwif->mate->serialized = hwif->serialized = 1; - } + ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base)) + hwif->host->host_flags |= IDE_HFLAG_SERIALIZE; if (d->max_sectors) hwif->rqsize = d->max_sectors; -- cgit From dc09c78425de89c80c51319c3fbb939f7960c59c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 29 Dec 2008 20:27:36 +0100 Subject: ide: struct device - replace bus_id with dev_name(), dev_set_name() Acked-by: Greg Kroah-Hartman Signed-off-by: Kay Sievers Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index c1cd1af2646..aaefd70dbff 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -642,7 +642,7 @@ static int ide_register_port(ide_hwif_t *hwif) int ret; /* register with global device tree */ - strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE); + dev_set_name(&hwif->gendev, hwif->name); hwif->gendev.driver_data = hwif; if (hwif->gendev.parent == NULL) { if (hwif->dev) @@ -1315,7 +1315,7 @@ static void hwif_register_devices(ide_hwif_t *hwif) if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) continue; - snprintf(dev->bus_id, BUS_ID_SIZE, "%u.%u", hwif->index, i); + dev_set_name(dev, "%u.%u", hwif->index, i); dev->parent = &hwif->gendev; dev->bus = &ide_bus_type; dev->driver_data = drive; -- cgit From b002415012f518e6940fabb77e35f0fb21b3640d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:36 +0100 Subject: ide: remove redundant code from ide_end_drive_cmd() rq->errors is overwritten later in this function. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index f776bd47501..26d3f3cacc8 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -291,9 +291,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *task = (ide_task_t *)rq->special; - if (rq->errors == 0) - rq->errors = !OK_STAT(stat, ATA_DRDY, BAD_STAT); - if (task) { struct ide_taskfile *tf = &task->tf; -- cgit From 047140ae2ecf954c0c44ea27cb1ae89138671bc1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:36 +0100 Subject: ide: remove inline tags from ide-probe.c Let the compiler handle it. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index aaefd70dbff..6d11f180bd1 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -110,8 +110,8 @@ static void ide_disk_init_mult_count(ide_drive_t *drive) * read and parse the results. This function is run with * interrupts disabled. */ - -static inline void do_identify (ide_drive_t *drive, u8 cmd) + +static void do_identify(ide_drive_t *drive, u8 cmd) { ide_hwif_t *hwif = HWIF(drive); u16 *id = drive->id; @@ -554,8 +554,8 @@ static void enable_nest (ide_drive_t *drive) * 1 device was found * (note: IDE_DFLAG_PRESENT might still be not set) */ - -static inline u8 probe_for_drive (ide_drive_t *drive) + +static u8 probe_for_drive(ide_drive_t *drive) { char *m; -- cgit From 2f996acb6191b6b5f188eca1d1ad76cf1d8ecf76 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:36 +0100 Subject: ide: checkpatch.pl fixes for ide-lib.c Fix following errors/warnings detected by checkpatch.pl: - WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable - WARNING: space prohibited between function name and open parenthesis '(' - ERROR: trailing whitespace - ERROR: trailing statements should be on next line - WARNING: printk() should include KERN_ facility level Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-lib.c | 95 +++++++++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 41 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 1932119dfa0..7913ad5d497 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -43,7 +43,6 @@ const char *ide_xfer_verbose(u8 mode) return s; } - EXPORT_SYMBOL(ide_xfer_verbose); /** @@ -87,7 +86,7 @@ static u8 ide_rate_filter(ide_drive_t *drive, u8 speed) * This is used by most chipset support modules when "auto-tuning". */ -u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode) +u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode) { u16 *id = drive->id; int pio_mode = -1, overridden = 0; @@ -131,7 +130,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode) return pio_mode; } - EXPORT_SYMBOL_GPL(ide_get_best_pio_mode); /* req_pio == "255" for auto-tune */ @@ -162,7 +160,6 @@ void ide_set_pio(ide_drive_t *drive, u8 req_pio) (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio); } - EXPORT_SYMBOL_GPL(ide_set_pio); /** @@ -173,7 +170,7 @@ EXPORT_SYMBOL_GPL(ide_set_pio); * Enable or disable bounce buffering for the device. Drives move * between PIO and DMA and that changes the rules we need. */ - + void ide_toggle_bounce(ide_drive_t *drive, int on) { u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */ @@ -243,14 +240,13 @@ int ide_set_dma_mode(ide_drive_t *drive, const u8 mode) return ide_config_drive_speed(drive, mode); } } - EXPORT_SYMBOL_GPL(ide_set_dma_mode); /** * ide_set_xfer_rate - set transfer rate * @drive: drive to set * @rate: speed to attempt to set - * + * * General helper for setting the speed of an IDE device. This * function knows about user enforced limits from the configuration * which ->set_pio_mode/->set_dma_mode does not. @@ -286,7 +282,7 @@ static void ide_dump_opcode(ide_drive_t *drive) if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) task = rq->special; - printk("ide: failed opcode was: "); + printk(KERN_ERR "ide: failed opcode was: "); if (task == NULL) printk(KERN_CONT "unknown\n"); else @@ -324,44 +320,55 @@ static void ide_dump_sector(ide_drive_t *drive) drive->hwif->tp_ops->tf_read(drive, &task); if (lba48 || (tf->device & ATA_LBA)) - printk(", LBAsect=%llu", + printk(KERN_CONT ", LBAsect=%llu", (unsigned long long)ide_get_lba_addr(tf, lba48)); else - printk(", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam, - tf->device & 0xf, tf->lbal); + printk(KERN_CONT ", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam, + tf->device & 0xf, tf->lbal); } static void ide_dump_ata_error(ide_drive_t *drive, u8 err) { - printk("{ "); - if (err & ATA_ABORTED) printk("DriveStatusError "); + printk(KERN_ERR "{ "); + if (err & ATA_ABORTED) + printk(KERN_CONT "DriveStatusError "); if (err & ATA_ICRC) - printk((err & ATA_ABORTED) ? "BadCRC " : "BadSector "); - if (err & ATA_UNC) printk("UncorrectableError "); - if (err & ATA_IDNF) printk("SectorIdNotFound "); - if (err & ATA_TRK0NF) printk("TrackZeroNotFound "); - if (err & ATA_AMNF) printk("AddrMarkNotFound "); - printk("}"); + printk(KERN_CONT "%s", + (err & ATA_ABORTED) ? "BadCRC " : "BadSector "); + if (err & ATA_UNC) + printk(KERN_CONT "UncorrectableError "); + if (err & ATA_IDNF) + printk(KERN_CONT "SectorIdNotFound "); + if (err & ATA_TRK0NF) + printk(KERN_CONT "TrackZeroNotFound "); + if (err & ATA_AMNF) + printk(KERN_CONT "AddrMarkNotFound "); + printk(KERN_CONT "}"); if ((err & (ATA_BBK | ATA_ABORTED)) == ATA_BBK || (err & (ATA_UNC | ATA_IDNF | ATA_AMNF))) { ide_dump_sector(drive); if (HWGROUP(drive) && HWGROUP(drive)->rq) - printk(", sector=%llu", + printk(KERN_CONT ", sector=%llu", (unsigned long long)HWGROUP(drive)->rq->sector); } - printk("\n"); + printk(KERN_CONT "\n"); } static void ide_dump_atapi_error(ide_drive_t *drive, u8 err) { - printk("{ "); - if (err & ATAPI_ILI) printk("IllegalLengthIndication "); - if (err & ATAPI_EOM) printk("EndOfMedia "); - if (err & ATA_ABORTED) printk("AbortedCommand "); - if (err & ATA_MCR) printk("MediaChangeRequested "); - if (err & ATAPI_LFS) printk("LastFailedSense=0x%02x ", - (err & ATAPI_LFS) >> 4); - printk("}\n"); + printk(KERN_ERR "{ "); + if (err & ATAPI_ILI) + printk(KERN_CONT "IllegalLengthIndication "); + if (err & ATAPI_EOM) + printk(KERN_CONT "EndOfMedia "); + if (err & ATA_ABORTED) + printk(KERN_CONT "AbortedCommand "); + if (err & ATA_MCR) + printk(KERN_CONT "MediaChangeRequested "); + if (err & ATAPI_LFS) + printk(KERN_CONT "LastFailedSense=0x%02x ", + (err & ATAPI_LFS) >> 4); + printk(KERN_CONT "}\n"); } /** @@ -381,22 +388,29 @@ u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) u8 err = 0; local_irq_save(flags); - printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); + printk(KERN_ERR "%s: %s: status=0x%02x { ", drive->name, msg, stat); if (stat & ATA_BUSY) - printk("Busy "); + printk(KERN_CONT "Busy "); else { - if (stat & ATA_DRDY) printk("DriveReady "); - if (stat & ATA_DF) printk("DeviceFault "); - if (stat & ATA_DSC) printk("SeekComplete "); - if (stat & ATA_DRQ) printk("DataRequest "); - if (stat & ATA_CORR) printk("CorrectedError "); - if (stat & ATA_IDX) printk("Index "); - if (stat & ATA_ERR) printk("Error "); + if (stat & ATA_DRDY) + printk(KERN_CONT "DriveReady "); + if (stat & ATA_DF) + printk(KERN_CONT "DeviceFault "); + if (stat & ATA_DSC) + printk(KERN_CONT "SeekComplete "); + if (stat & ATA_DRQ) + printk(KERN_CONT "DataRequest "); + if (stat & ATA_CORR) + printk(KERN_CONT "CorrectedError "); + if (stat & ATA_IDX) + printk(KERN_CONT "Index "); + if (stat & ATA_ERR) + printk(KERN_CONT "Error "); } - printk("}\n"); + printk(KERN_CONT "}\n"); if ((stat & (ATA_BUSY | ATA_ERR)) == ATA_ERR) { err = ide_read_error(drive); - printk("%s: %s: error=0x%02x ", drive->name, msg, err); + printk(KERN_ERR "%s: %s: error=0x%02x ", drive->name, msg, err); if (drive->media == ide_disk) ide_dump_ata_error(drive, err); else @@ -406,5 +420,4 @@ u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) local_irq_restore(flags); return err; } - EXPORT_SYMBOL(ide_dump_status); -- cgit From 1d35364acbd5ab7d67bb39cfc5dd3ed0fbefb4b8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:37 +0100 Subject: ide: use ATA_DMA_* defines in ide-dma-sff.c In few places open-coded values were still being used. Fix it. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma-sff.c | 52 +++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 29 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c index 1f2a5f56f81..f6d2d44d8a9 100644 --- a/drivers/ide/ide-dma-sff.c +++ b/drivers/ide/ide-dma-sff.c @@ -176,15 +176,10 @@ int ide_dma_setup(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->hwgroup->rq; - unsigned int reading; + unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; u8 dma_stat; - if (rq_data_dir(rq)) - reading = 0; - else - reading = 1 << 3; - /* fall back to pio! */ if (!ide_build_dmatable(drive, rq)) { ide_map_sg(drive, rq); @@ -209,10 +204,11 @@ int ide_dma_setup(ide_drive_t *drive) /* clear INTR & ERROR flags */ if (mmio) - writeb(dma_stat | 6, + writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); else - outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); + outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, + hwif->dma_base + ATA_DMA_STATUS); drive->waiting_for_dma = 1; return 0; @@ -246,14 +242,13 @@ static int dma_timer_expiry(ide_drive_t *drive) hwif->hwgroup->expiry = NULL; /* one free ride for now */ - /* 1 dmaing, 2 error, 4 intr */ - if (dma_stat & 2) /* ERROR */ + if (dma_stat & ATA_DMA_ERR) /* ERROR */ return -1; - if (dma_stat & 1) /* DMAing */ + if (dma_stat & ATA_DMA_ACTIVE) /* DMAing */ return WAIT_CMD; - if (dma_stat & 4) /* Got an Interrupt */ + if (dma_stat & ATA_DMA_INTR) /* Got an Interrupt */ return WAIT_CMD; return 0; /* Status is unknown -- reset the bus */ @@ -279,12 +274,11 @@ void ide_dma_start(ide_drive_t *drive) */ if (hwif->host_flags & IDE_HFLAG_MMIO) { dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - /* start DMA */ - writeb(dma_cmd | 1, + writeb(dma_cmd | ATA_DMA_START, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); } else { dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); - outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); + outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD); } wmb(); @@ -296,19 +290,18 @@ int ide_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; - u8 dma_stat = 0, dma_cmd = 0; + u8 dma_stat = 0, dma_cmd = 0, mask; drive->waiting_for_dma = 0; + /* stop DMA */ if (mmio) { - /* get DMA command mode */ dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); - /* stop DMA */ - writeb(dma_cmd & ~1, + writeb(dma_cmd & ~ATA_DMA_START, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); } else { dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); - outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); + outb(dma_cmd & ~ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD); } /* get DMA status */ @@ -316,16 +309,21 @@ int ide_dma_end(ide_drive_t *drive) if (mmio) /* clear the INTR & ERROR bits */ - writeb(dma_stat | 6, + writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); else - outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); + outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, + hwif->dma_base + ATA_DMA_STATUS); /* purge DMA mappings */ ide_destroy_dmatable(drive); - /* verify good DMA status */ wmb(); - return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; + + /* verify good DMA status */ + mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR; + if ((dma_stat & mask) != ATA_DMA_INTR) + return 0x10 | dma_stat; + return 0; } EXPORT_SYMBOL_GPL(ide_dma_end); @@ -335,11 +333,7 @@ int ide_dma_test_irq(ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); - /* return 1 if INTR asserted */ - if ((dma_stat & 4) == 4) - return 1; - - return 0; + return (dma_stat & ATA_DMA_INTR) ? 1 : 0; } EXPORT_SYMBOL_GPL(ide_dma_test_irq); -- cgit From e2984c628c924442132304ae662da433f41c05c9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:37 +0100 Subject: ide: move Power Management support to ide-pm.c There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Makefile | 2 +- drivers/ide/ide-io.c | 159 ---------------------------------- drivers/ide/ide-pm.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/ide/ide.c | 74 ---------------- 4 files changed, 236 insertions(+), 234 deletions(-) create mode 100644 drivers/ide/ide-pm.c (limited to 'drivers/ide') diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 7818d402b18..bdc7b81bc04 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -5,7 +5,7 @@ EXTRA_CFLAGS += -Idrivers/ide ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ - ide-taskfile.o ide-park.o ide-pio-blacklist.o + ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o # core IDE code ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 26d3f3cacc8..ecacc008fda 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -120,98 +120,6 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) } EXPORT_SYMBOL(ide_end_request); -static void ide_complete_power_step(ide_drive_t *drive, struct request *rq) -{ - struct request_pm_state *pm = rq->data; - -#ifdef DEBUG_PM - printk(KERN_INFO "%s: complete_power_step(step: %d)\n", - drive->name, pm->pm_step); -#endif - if (drive->media != ide_disk) - return; - - switch (pm->pm_step) { - case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ - if (pm->pm_state == PM_EVENT_FREEZE) - pm->pm_step = IDE_PM_COMPLETED; - else - pm->pm_step = IDE_PM_STANDBY; - break; - case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ - pm->pm_step = IDE_PM_COMPLETED; - break; - case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ - pm->pm_step = IDE_PM_IDLE; - break; - case IDE_PM_IDLE: /* Resume step 2 (idle)*/ - pm->pm_step = IDE_PM_RESTORE_DMA; - break; - } -} - -static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) -{ - struct request_pm_state *pm = rq->data; - ide_task_t *args = rq->special; - - memset(args, 0, sizeof(*args)); - - switch (pm->pm_step) { - case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ - if (drive->media != ide_disk) - break; - /* Not supported? Switch to next step now. */ - if (ata_id_flush_enabled(drive->id) == 0 || - (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) { - ide_complete_power_step(drive, rq); - return ide_stopped; - } - if (ata_id_flush_ext_enabled(drive->id)) - args->tf.command = ATA_CMD_FLUSH_EXT; - else - args->tf.command = ATA_CMD_FLUSH; - goto out_do_tf; - case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ - args->tf.command = ATA_CMD_STANDBYNOW1; - goto out_do_tf; - case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ - ide_set_max_pio(drive); - /* - * skip IDE_PM_IDLE for ATAPI devices - */ - if (drive->media != ide_disk) - pm->pm_step = IDE_PM_RESTORE_DMA; - else - ide_complete_power_step(drive, rq); - return ide_stopped; - case IDE_PM_IDLE: /* Resume step 2 (idle) */ - args->tf.command = ATA_CMD_IDLEIMMEDIATE; - goto out_do_tf; - case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ - /* - * Right now, all we do is call ide_set_dma(drive), - * we could be smarter and check for current xfer_speed - * in struct drive etc... - */ - if (drive->hwif->dma_ops == NULL) - break; - /* - * TODO: respect IDE_DFLAG_USING_DMA - */ - ide_set_dma(drive); - break; - } - - pm->pm_step = IDE_PM_COMPLETED; - return ide_stopped; - -out_do_tf: - args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - args->data_phase = TASKFILE_NO_DATA; - return do_rw_taskfile(drive, args); -} - /** * ide_end_dequeued_request - complete an IDE I/O * @drive: IDE device for the I/O @@ -236,39 +144,6 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, } EXPORT_SYMBOL_GPL(ide_end_dequeued_request); - -/** - * ide_complete_pm_request - end the current Power Management request - * @drive: target drive - * @rq: request - * - * This function cleans up the current PM request and stops the queue - * if necessary. - */ -static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) -{ - struct request_queue *q = drive->queue; - unsigned long flags; - -#ifdef DEBUG_PM - printk("%s: completing PM request, %s\n", drive->name, - blk_pm_suspend_request(rq) ? "suspend" : "resume"); -#endif - spin_lock_irqsave(q->queue_lock, flags); - if (blk_pm_suspend_request(rq)) { - blk_stop_queue(q); - } else { - drive->dev_flags &= ~IDE_DFLAG_BLOCKED; - blk_start_queue(q); - } - spin_unlock_irqrestore(q->queue_lock, flags); - - drive->hwif->hwgroup->rq = NULL; - - if (blk_end_request(rq, 0, 0)) - BUG(); -} - /** * ide_end_drive_cmd - end an explicit drive command * @drive: command @@ -697,40 +572,6 @@ static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) } } -static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) -{ - struct request_pm_state *pm = rq->data; - - if (blk_pm_suspend_request(rq) && - pm->pm_step == IDE_PM_START_SUSPEND) - /* Mark drive blocked when starting the suspend sequence. */ - drive->dev_flags |= IDE_DFLAG_BLOCKED; - else if (blk_pm_resume_request(rq) && - pm->pm_step == IDE_PM_START_RESUME) { - /* - * The first thing we do on wakeup is to wait for BSY bit to - * go away (with a looong timeout) as a drive on this hwif may - * just be POSTing itself. - * We do that before even selecting as the "other" device on - * the bus may be broken enough to walk on our toes at this - * point. - */ - ide_hwif_t *hwif = drive->hwif; - int rc; -#ifdef DEBUG_PM - printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name); -#endif - rc = ide_wait_not_busy(hwif, 35000); - if (rc) - printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); - SELECT_DRIVE(drive); - hwif->tp_ops->set_irq(hwif, 1); - rc = ide_wait_not_busy(hwif, 100000); - if (rc) - printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); - } -} - /** * start_request - start of I/O and command issuing for IDE * diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c new file mode 100644 index 00000000000..8282c6086e6 --- /dev/null +++ b/drivers/ide/ide-pm.c @@ -0,0 +1,235 @@ +#include +#include +#include + +int generic_ide_suspend(struct device *dev, pm_message_t mesg) +{ + ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); + ide_hwif_t *hwif = HWIF(drive); + struct request *rq; + struct request_pm_state rqpm; + ide_task_t args; + int ret; + + /* call ACPI _GTM only once */ + if ((drive->dn & 1) == 0 || pair == NULL) + ide_acpi_get_timing(hwif); + + memset(&rqpm, 0, sizeof(rqpm)); + memset(&args, 0, sizeof(args)); + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_PM_SUSPEND; + rq->special = &args; + rq->data = &rqpm; + rqpm.pm_step = IDE_PM_START_SUSPEND; + if (mesg.event == PM_EVENT_PRETHAW) + mesg.event = PM_EVENT_FREEZE; + rqpm.pm_state = mesg.event; + + ret = blk_execute_rq(drive->queue, NULL, rq, 0); + blk_put_request(rq); + + /* call ACPI _PS3 only after both devices are suspended */ + if (ret == 0 && ((drive->dn & 1) || pair == NULL)) + ide_acpi_set_state(hwif, 0); + + return ret; +} + +int generic_ide_resume(struct device *dev) +{ + ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); + ide_hwif_t *hwif = HWIF(drive); + struct request *rq; + struct request_pm_state rqpm; + ide_task_t args; + int err; + + /* call ACPI _PS0 / _STM only once */ + if ((drive->dn & 1) == 0 || pair == NULL) { + ide_acpi_set_state(hwif, 1); + ide_acpi_push_timing(hwif); + } + + ide_acpi_exec_tfs(drive); + + memset(&rqpm, 0, sizeof(rqpm)); + memset(&args, 0, sizeof(args)); + rq = blk_get_request(drive->queue, READ, __GFP_WAIT); + rq->cmd_type = REQ_TYPE_PM_RESUME; + rq->cmd_flags |= REQ_PREEMPT; + rq->special = &args; + rq->data = &rqpm; + rqpm.pm_step = IDE_PM_START_RESUME; + rqpm.pm_state = PM_EVENT_ON; + + err = blk_execute_rq(drive->queue, NULL, rq, 1); + blk_put_request(rq); + + if (err == 0 && dev->driver) { + ide_driver_t *drv = to_ide_driver(dev->driver); + + if (drv->resume) + drv->resume(drive); + } + + return err; +} + +void ide_complete_power_step(ide_drive_t *drive, struct request *rq) +{ + struct request_pm_state *pm = rq->data; + +#ifdef DEBUG_PM + printk(KERN_INFO "%s: complete_power_step(step: %d)\n", + drive->name, pm->pm_step); +#endif + if (drive->media != ide_disk) + return; + + switch (pm->pm_step) { + case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ + if (pm->pm_state == PM_EVENT_FREEZE) + pm->pm_step = IDE_PM_COMPLETED; + else + pm->pm_step = IDE_PM_STANDBY; + break; + case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ + pm->pm_step = IDE_PM_COMPLETED; + break; + case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ + pm->pm_step = IDE_PM_IDLE; + break; + case IDE_PM_IDLE: /* Resume step 2 (idle)*/ + pm->pm_step = IDE_PM_RESTORE_DMA; + break; + } +} + +ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) +{ + struct request_pm_state *pm = rq->data; + ide_task_t *args = rq->special; + + memset(args, 0, sizeof(*args)); + + switch (pm->pm_step) { + case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ + if (drive->media != ide_disk) + break; + /* Not supported? Switch to next step now. */ + if (ata_id_flush_enabled(drive->id) == 0 || + (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) { + ide_complete_power_step(drive, rq); + return ide_stopped; + } + if (ata_id_flush_ext_enabled(drive->id)) + args->tf.command = ATA_CMD_FLUSH_EXT; + else + args->tf.command = ATA_CMD_FLUSH; + goto out_do_tf; + case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ + args->tf.command = ATA_CMD_STANDBYNOW1; + goto out_do_tf; + case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ + ide_set_max_pio(drive); + /* + * skip IDE_PM_IDLE for ATAPI devices + */ + if (drive->media != ide_disk) + pm->pm_step = IDE_PM_RESTORE_DMA; + else + ide_complete_power_step(drive, rq); + return ide_stopped; + case IDE_PM_IDLE: /* Resume step 2 (idle) */ + args->tf.command = ATA_CMD_IDLEIMMEDIATE; + goto out_do_tf; + case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ + /* + * Right now, all we do is call ide_set_dma(drive), + * we could be smarter and check for current xfer_speed + * in struct drive etc... + */ + if (drive->hwif->dma_ops == NULL) + break; + /* + * TODO: respect IDE_DFLAG_USING_DMA + */ + ide_set_dma(drive); + break; + } + + pm->pm_step = IDE_PM_COMPLETED; + return ide_stopped; + +out_do_tf: + args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + args->data_phase = TASKFILE_NO_DATA; + return do_rw_taskfile(drive, args); +} + +/** + * ide_complete_pm_request - end the current Power Management request + * @drive: target drive + * @rq: request + * + * This function cleans up the current PM request and stops the queue + * if necessary. + */ +void ide_complete_pm_request(ide_drive_t *drive, struct request *rq) +{ + struct request_queue *q = drive->queue; + unsigned long flags; + +#ifdef DEBUG_PM + printk("%s: completing PM request, %s\n", drive->name, + blk_pm_suspend_request(rq) ? "suspend" : "resume"); +#endif + spin_lock_irqsave(q->queue_lock, flags); + if (blk_pm_suspend_request(rq)) { + blk_stop_queue(q); + } else { + drive->dev_flags &= ~IDE_DFLAG_BLOCKED; + blk_start_queue(q); + } + spin_unlock_irqrestore(q->queue_lock, flags); + + drive->hwif->hwgroup->rq = NULL; + + if (blk_end_request(rq, 0, 0)) + BUG(); +} + +void ide_check_pm_state(ide_drive_t *drive, struct request *rq) +{ + struct request_pm_state *pm = rq->data; + + if (blk_pm_suspend_request(rq) && + pm->pm_step == IDE_PM_START_SUSPEND) + /* Mark drive blocked when starting the suspend sequence. */ + drive->dev_flags |= IDE_DFLAG_BLOCKED; + else if (blk_pm_resume_request(rq) && + pm->pm_step == IDE_PM_START_RESUME) { + /* + * The first thing we do on wakeup is to wait for BSY bit to + * go away (with a looong timeout) as a drive on this hwif may + * just be POSTing itself. + * We do that before even selecting as the "other" device on + * the bus may be broken enough to walk on our toes at this + * point. + */ + ide_hwif_t *hwif = drive->hwif; + int rc; +#ifdef DEBUG_PM + printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name); +#endif + rc = ide_wait_not_busy(hwif, 35000); + if (rc) + printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); + SELECT_DRIVE(drive); + hwif->tp_ops->set_irq(hwif, 1); + rc = ide_wait_not_busy(hwif, 100000); + if (rc) + printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); + } +} diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 41d04205354..f0f09f702e9 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -388,80 +388,6 @@ ide_ext_devset_rw_sync(unmaskirq, unmaskirq); ide_ext_devset_rw_sync(using_dma, using_dma); __IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode); -static int generic_ide_suspend(struct device *dev, pm_message_t mesg) -{ - ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); - ide_hwif_t *hwif = HWIF(drive); - struct request *rq; - struct request_pm_state rqpm; - ide_task_t args; - int ret; - - /* call ACPI _GTM only once */ - if ((drive->dn & 1) == 0 || pair == NULL) - ide_acpi_get_timing(hwif); - - memset(&rqpm, 0, sizeof(rqpm)); - memset(&args, 0, sizeof(args)); - rq = blk_get_request(drive->queue, READ, __GFP_WAIT); - rq->cmd_type = REQ_TYPE_PM_SUSPEND; - rq->special = &args; - rq->data = &rqpm; - rqpm.pm_step = IDE_PM_START_SUSPEND; - if (mesg.event == PM_EVENT_PRETHAW) - mesg.event = PM_EVENT_FREEZE; - rqpm.pm_state = mesg.event; - - ret = blk_execute_rq(drive->queue, NULL, rq, 0); - blk_put_request(rq); - - /* call ACPI _PS3 only after both devices are suspended */ - if (ret == 0 && ((drive->dn & 1) || pair == NULL)) - ide_acpi_set_state(hwif, 0); - - return ret; -} - -static int generic_ide_resume(struct device *dev) -{ - ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); - ide_hwif_t *hwif = HWIF(drive); - struct request *rq; - struct request_pm_state rqpm; - ide_task_t args; - int err; - - /* call ACPI _PS0 / _STM only once */ - if ((drive->dn & 1) == 0 || pair == NULL) { - ide_acpi_set_state(hwif, 1); - ide_acpi_push_timing(hwif); - } - - ide_acpi_exec_tfs(drive); - - memset(&rqpm, 0, sizeof(rqpm)); - memset(&args, 0, sizeof(args)); - rq = blk_get_request(drive->queue, READ, __GFP_WAIT); - rq->cmd_type = REQ_TYPE_PM_RESUME; - rq->cmd_flags |= REQ_PREEMPT; - rq->special = &args; - rq->data = &rqpm; - rqpm.pm_step = IDE_PM_START_RESUME; - rqpm.pm_state = PM_EVENT_ON; - - err = blk_execute_rq(drive->queue, NULL, rq, 1); - blk_put_request(rq); - - if (err == 0 && dev->driver) { - ide_driver_t *drv = to_ide_driver(dev->driver); - - if (drv->resume) - drv->resume(drive); - } - - return err; -} - /** * ide_device_get - get an additional reference to a ide_drive_t * @drive: device to get a reference to -- cgit From 7f92b11c1cc0e865fc64f3148eda87fff74920e1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:37 +0100 Subject: ide: move legacy ISA/VLB ports handling to ide-legacy.c (v2) * Move legacy ISA/VLB ports handling from ide-probe.c to ide-legacy.c. * Add CONFIG_IDE_LEGACY config option to be selected by host drivers needing ide-legacy.c. v2: Fix CONFIG_IDE_LEGACY not being defined in Kconfig. (from Takashi Iwai ) There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Kconfig | 8 +++++++ drivers/ide/Makefile | 1 + drivers/ide/ide-legacy.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/ide/ide-probe.c | 56 ---------------------------------------------- 4 files changed, 67 insertions(+), 56 deletions(-) create mode 100644 drivers/ide/ide-legacy.c (limited to 'drivers/ide') diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e6857e01d1b..7a0a84b042c 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -62,6 +62,9 @@ config IDE_TIMINGS config IDE_ATAPI bool +config IDE_LEGACY + bool + config BLK_DEV_IDE_SATA bool "Support for SATA (deprecated; conflicts with libata SATA driver)" default n @@ -856,6 +859,7 @@ config BLK_DEV_4DRIVES config BLK_DEV_ALI14XX tristate "ALI M14xx support" select IDE_TIMINGS + select IDE_LEGACY help This driver is enabled at runtime using the "ali14xx.probe" kernel boot parameter. It enables support for the secondary IDE interface @@ -866,6 +870,7 @@ config BLK_DEV_ALI14XX config BLK_DEV_DTC2278 tristate "DTC-2278 support" + select IDE_LEGACY help This driver is enabled at runtime using the "dtc2278.probe" kernel boot parameter. It enables support for the secondary IDE interface @@ -876,6 +881,7 @@ config BLK_DEV_DTC2278 config BLK_DEV_HT6560B tristate "Holtek HT6560B support" select IDE_TIMINGS + select IDE_LEGACY help This driver is enabled at runtime using the "ht6560b.probe" kernel boot parameter. It enables support for the secondary IDE interface @@ -886,6 +892,7 @@ config BLK_DEV_HT6560B config BLK_DEV_QD65XX tristate "QDI QD65xx support" select IDE_TIMINGS + select IDE_LEGACY help This driver is enabled at runtime using the "qd65xx.probe" kernel boot parameter. It permits faster I/O speeds to be set. See the @@ -894,6 +901,7 @@ config BLK_DEV_QD65XX config BLK_DEV_UMC8672 tristate "UMC-8672 support" + select IDE_LEGACY help This driver is enabled at runtime using the "umc8672.probe" kernel boot parameter. It enables support for the secondary IDE interface diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index bdc7b81bc04..177e3f8523e 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -15,6 +15,7 @@ ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o ide-core-$(CONFIG_BLK_DEV_IDEDMA_SFF) += ide-dma-sff.o ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o +ide-core-$(CONFIG_IDE_LEGACY) += ide-legacy.o obj-$(CONFIG_IDE) += ide-core.o diff --git a/drivers/ide/ide-legacy.c b/drivers/ide/ide-legacy.c new file mode 100644 index 00000000000..8c5dcbf2254 --- /dev/null +++ b/drivers/ide/ide-legacy.c @@ -0,0 +1,58 @@ +#include +#include + +static void ide_legacy_init_one(hw_regs_t **hws, hw_regs_t *hw, + u8 port_no, const struct ide_port_info *d, + unsigned long config) +{ + unsigned long base, ctl; + int irq; + + if (port_no == 0) { + base = 0x1f0; + ctl = 0x3f6; + irq = 14; + } else { + base = 0x170; + ctl = 0x376; + irq = 15; + } + + if (!request_region(base, 8, d->name)) { + printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", + d->name, base, base + 7); + return; + } + + if (!request_region(ctl, 1, d->name)) { + printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", + d->name, ctl); + release_region(base, 8); + return; + } + + ide_std_init_ports(hw, base, ctl); + hw->irq = irq; + hw->chipset = d->chipset; + hw->config = config; + + hws[port_no] = hw; +} + +int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config) +{ + hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL }; + + memset(&hw, 0, sizeof(hw)); + + if ((d->host_flags & IDE_HFLAG_QD_2ND_PORT) == 0) + ide_legacy_init_one(hws, &hw[0], 0, d, config); + ide_legacy_init_one(hws, &hw[1], 1, d, config); + + if (hws[0] == NULL && hws[1] == NULL && + (d->host_flags & IDE_HFLAG_SINGLE)) + return -ENOENT; + + return ide_host_add(d, hws, NULL); +} +EXPORT_SYMBOL_GPL(ide_legacy_device_add); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 6d11f180bd1..2333a5a8351 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1755,59 +1755,3 @@ void ide_port_scan(ide_hwif_t *hwif) ide_proc_port_register_devices(hwif); } EXPORT_SYMBOL_GPL(ide_port_scan); - -static void ide_legacy_init_one(hw_regs_t **hws, hw_regs_t *hw, - u8 port_no, const struct ide_port_info *d, - unsigned long config) -{ - unsigned long base, ctl; - int irq; - - if (port_no == 0) { - base = 0x1f0; - ctl = 0x3f6; - irq = 14; - } else { - base = 0x170; - ctl = 0x376; - irq = 15; - } - - if (!request_region(base, 8, d->name)) { - printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", - d->name, base, base + 7); - return; - } - - if (!request_region(ctl, 1, d->name)) { - printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", - d->name, ctl); - release_region(base, 8); - return; - } - - ide_std_init_ports(hw, base, ctl); - hw->irq = irq; - hw->chipset = d->chipset; - hw->config = config; - - hws[port_no] = hw; -} - -int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config) -{ - hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL }; - - memset(&hw, 0, sizeof(hw)); - - if ((d->host_flags & IDE_HFLAG_QD_2ND_PORT) == 0) - ide_legacy_init_one(hws, &hw[0], 0, d, config); - ide_legacy_init_one(hws, &hw[1], 1, d, config); - - if (hws[0] == NULL && hws[1] == NULL && - (d->host_flags & IDE_HFLAG_SINGLE)) - return -ENOENT; - - return ide_host_add(d, hws, NULL); -} -EXPORT_SYMBOL_GPL(ide_legacy_device_add); -- cgit From d688b72c90a7faf13c070d4ebb63cacdf481de32 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:37 +0100 Subject: ide: remove superfluous local_irq_{save,restore}() from ide_dump_status() No reason to run this function with local IRQs off. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-lib.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 7913ad5d497..9f6e33d8a8b 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -384,10 +384,8 @@ static void ide_dump_atapi_error(ide_drive_t *drive, u8 err) u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) { - unsigned long flags; u8 err = 0; - local_irq_save(flags); printk(KERN_ERR "%s: %s: status=0x%02x { ", drive->name, msg, stat); if (stat & ATA_BUSY) printk(KERN_CONT "Busy "); @@ -417,7 +415,6 @@ u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) ide_dump_atapi_error(drive, err); } ide_dump_opcode(drive); - local_irq_restore(flags); return err; } EXPORT_SYMBOL(ide_dump_status); -- cgit From 94b9efdf5a3ec78bc31281ea3ba80028ce4ab057 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:38 +0100 Subject: ide: push local_irq_{save,restore}() to do_identify() Push local_irq_{save,restore}() from actual_try_to_identify() to do_identify() and remove no longer needed local_irq_enable(). Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 2333a5a8351..a64ec259f3d 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -116,14 +116,16 @@ static void do_identify(ide_drive_t *drive, u8 cmd) ide_hwif_t *hwif = HWIF(drive); u16 *id = drive->id; char *m = (char *)&id[ATA_ID_PROD]; + unsigned long flags; int bswap = 1, is_cfa; + /* local CPU only; some systems need this */ + local_irq_save(flags); /* read 512 bytes of id info */ hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); + local_irq_restore(flags); drive->dev_flags |= IDE_DFLAG_ID_READ; - - local_irq_enable(); #ifdef DEBUG printk(KERN_INFO "%s: dumping identify data\n", drive->name); ide_dump_identify((u8 *)id); @@ -306,17 +308,12 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) s = tp_ops->read_status(hwif); if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) { - unsigned long flags; - - /* local CPU only; some systems need this */ - local_irq_save(flags); /* drive returned ID */ do_identify(drive, cmd); /* drive responded with ID */ rc = 0; /* clear drive IRQ */ (void)tp_ops->read_status(hwif); - local_irq_restore(flags); } else { /* drive refused ID */ rc = 2; -- cgit From 519d68082e56fe4a5a7d273465323a95cbe5a33f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:38 +0100 Subject: ide-cd: remove dead dsc_overlap setting dsc_overlap setting is not useful anymore for ide-cd so remove "dsc_overlap" /proc setting, disallow changing the setting through HDIO_SET_NICE ioctl and cleanup ide_cd{rom_setup,_release}(). Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 15 +-------------- drivers/ide/ide-ioctls.c | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ea35e94d098..5daa4dd1b01 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1831,13 +1831,6 @@ static ide_proc_entry_t idecd_proc[] = { { NULL, 0, NULL, NULL } }; -ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); - -static const struct ide_proc_devset idecd_settings[] = { - IDE_PROC_DEVSET(dsc_overlap, 0, 1), - { 0 }, -}; - static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive) { return idecd_proc; @@ -1845,7 +1838,7 @@ static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive) static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive) { - return idecd_settings; + return NULL; } #endif @@ -1945,11 +1938,6 @@ static int ide_cdrom_setup(ide_drive_t *drive) /* set correct block size */ blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); - if (drive->next != drive) - drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; - else - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; - if (ide_cdrom_register(drive, nslots)) { printk(KERN_ERR PFX "%s: %s failed to register device with the" " cdrom driver.\n", drive->name, __func__); @@ -1986,7 +1974,6 @@ static void ide_cd_release(struct kref *kref) kfree(info->toc); if (devinfo->handle == drive) unregister_cdrom(devinfo); - drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; drive->driver_data = NULL; blk_queue_prep_rq(drive->queue, NULL); g->private_data = NULL; diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index f9034765aa1..28232c64c34 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -95,7 +95,7 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) return -EPERM; if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) && - (drive->media == ide_disk || drive->media == ide_floppy || + (drive->media != ide_tape || (drive->dev_flags & IDE_DFLAG_SCSI))) return -EPERM; -- cgit From 3ee86dcdd273aa91cb9b4fe1e3d4f69035750a12 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:46 +0100 Subject: tx493x: fix indentation Trivial CodingStyle fixup for tx4938ide and tx4939ide drivers. Acked-by: Atsushi Nemoto Acked-by: Sergei Shtyltov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/tx4938ide.c | 10 +++++----- drivers/ide/tx4939ide.c | 42 +++++++++++++++++++++--------------------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c index 13b63e7fa35..0bb8b0ce456 100644 --- a/drivers/ide/tx4938ide.c +++ b/drivers/ide/tx4938ide.c @@ -216,16 +216,16 @@ static const struct ide_tp_ops tx4938ide_tp_ops = { #endif /* __BIG_ENDIAN */ static const struct ide_port_ops tx4938ide_port_ops = { - .set_pio_mode = tx4938ide_set_pio_mode, + .set_pio_mode = tx4938ide_set_pio_mode, }; static const struct ide_port_info tx4938ide_port_info __initdata = { - .port_ops = &tx4938ide_port_ops, + .port_ops = &tx4938ide_port_ops, #ifdef __BIG_ENDIAN - .tp_ops = &tx4938ide_tp_ops, + .tp_ops = &tx4938ide_tp_ops, #endif - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, - .pio_mask = ATA_PIO5, + .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, + .pio_mask = ATA_PIO5, }; static int __init tx4938ide_probe(struct platform_device *pdev) diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c index 97cd9e0f66f..65cd09773a0 100644 --- a/drivers/ide/tx4939ide.c +++ b/drivers/ide/tx4939ide.c @@ -623,33 +623,33 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { #endif /* __LITTLE_ENDIAN */ static const struct ide_port_ops tx4939ide_port_ops = { - .set_pio_mode = tx4939ide_set_pio_mode, - .set_dma_mode = tx4939ide_set_dma_mode, - .clear_irq = tx4939ide_clear_irq, - .cable_detect = tx4939ide_cable_detect, + .set_pio_mode = tx4939ide_set_pio_mode, + .set_dma_mode = tx4939ide_set_dma_mode, + .clear_irq = tx4939ide_clear_irq, + .cable_detect = tx4939ide_cable_detect, }; static const struct ide_dma_ops tx4939ide_dma_ops = { - .dma_host_set = tx4939ide_dma_host_set, - .dma_setup = tx4939ide_dma_setup, - .dma_exec_cmd = ide_dma_exec_cmd, - .dma_start = ide_dma_start, - .dma_end = tx4939ide_dma_end, - .dma_test_irq = tx4939ide_dma_test_irq, - .dma_lost_irq = ide_dma_lost_irq, - .dma_timeout = ide_dma_timeout, + .dma_host_set = tx4939ide_dma_host_set, + .dma_setup = tx4939ide_dma_setup, + .dma_exec_cmd = ide_dma_exec_cmd, + .dma_start = ide_dma_start, + .dma_end = tx4939ide_dma_end, + .dma_test_irq = tx4939ide_dma_test_irq, + .dma_lost_irq = ide_dma_lost_irq, + .dma_timeout = ide_dma_timeout, }; static const struct ide_port_info tx4939ide_port_info __initdata = { - .init_hwif = tx4939ide_init_hwif, - .init_dma = tx4939ide_init_dma, - .port_ops = &tx4939ide_port_ops, - .dma_ops = &tx4939ide_dma_ops, - .tp_ops = &tx4939ide_tp_ops, - .host_flags = IDE_HFLAG_MMIO, - .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, + .init_hwif = tx4939ide_init_hwif, + .init_dma = tx4939ide_init_dma, + .port_ops = &tx4939ide_port_ops, + .dma_ops = &tx4939ide_dma_ops, + .tp_ops = &tx4939ide_tp_ops, + .host_flags = IDE_HFLAG_MMIO, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA5, }; static int __init tx4939ide_probe(struct platform_device *pdev) -- cgit From b1d249e845efb07975183c62b4f75576c4a8d467 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:47 +0100 Subject: ide: remove chipset type fixup from ide_host_register() * Set chipset type explicitly in tx4938ide and tx4939ide host drivers (all other host drivers were updated already). * Remove no longer used chipset type fixup from ide_host_register(). Acked-by: Atsushi Nemoto Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 3 --- drivers/ide/tx4938ide.c | 1 + drivers/ide/tx4939ide.c | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index a64ec259f3d..291dacee52e 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1655,9 +1655,6 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, if (hwif == NULL) continue; - if (hwif->chipset == ide_unknown) - hwif->chipset = ide_generic; - if (hwif->present) hwif_register_devices(hwif); } diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c index 0bb8b0ce456..b4ef218072c 100644 --- a/drivers/ide/tx4938ide.c +++ b/drivers/ide/tx4938ide.c @@ -226,6 +226,7 @@ static const struct ide_port_info tx4938ide_port_info __initdata = { #endif .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, .pio_mask = ATA_PIO5, + .chipset = ide_generic, }; static int __init tx4938ide_probe(struct platform_device *pdev) diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c index 65cd09773a0..4a8c5a21bd4 100644 --- a/drivers/ide/tx4939ide.c +++ b/drivers/ide/tx4939ide.c @@ -650,6 +650,7 @@ static const struct ide_port_info tx4939ide_port_info __initdata = { .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA5, + .chipset = ide_generic, }; static int __init tx4939ide_probe(struct platform_device *pdev) -- cgit From 96d40941236722777c259775640b8880b7dc6f33 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:47 +0100 Subject: ide: small ide_register_port() cleanup Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 291dacee52e..7576a902a6a 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -641,14 +641,9 @@ static int ide_register_port(ide_hwif_t *hwif) /* register with global device tree */ dev_set_name(&hwif->gendev, hwif->name); hwif->gendev.driver_data = hwif; - if (hwif->gendev.parent == NULL) { - if (hwif->dev) - hwif->gendev.parent = hwif->dev; - else - /* Would like to do = &device_legacy */ - hwif->gendev.parent = NULL; - } + hwif->gendev.parent = hwif->dev; hwif->gendev.release = hwif_release_dev; + ret = device_register(&hwif->gendev); if (ret < 0) { printk(KERN_WARNING "IDE: %s: device_register error: %d\n", -- cgit From 24630dc68a499baec367d24285bc6b92207cc100 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:47 +0100 Subject: ide: factor out device type classifying from do_identify() Factor out device type classifying from do_identify() to ide_classify_ata_dev() and ide_classify_atapi_dev(). There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 154 +++++++++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 73 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 7576a902a6a..91f5faee740 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -101,6 +101,82 @@ static void ide_disk_init_mult_count(ide_drive_t *drive) } } +static void ide_classify_ata_dev(ide_drive_t *drive) +{ + u16 *id = drive->id; + char *m = (char *)&id[ATA_ID_PROD]; + int is_cfa = ata_id_is_cfa(id); + + /* CF devices are *not* removable in Linux definition of the term */ + if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7))) + drive->dev_flags |= IDE_DFLAG_REMOVABLE; + + drive->media = ide_disk; + + if (!ata_id_has_unload(drive->id)) + drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; + + printk(KERN_INFO "%s: %s, %s DISK drive\n", drive->name, m, + is_cfa ? "CFA" : "ATA"); +} + +static void ide_classify_atapi_dev(ide_drive_t *drive) +{ + u16 *id = drive->id; + char *m = (char *)&id[ATA_ID_PROD]; + u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f; + + printk(KERN_INFO "%s: %s, ATAPI ", drive->name, m); + switch (type) { + case ide_floppy: + if (!strstr(m, "CD-ROM")) { + if (!strstr(m, "oppy") && + !strstr(m, "poyp") && + !strstr(m, "ZIP")) + printk(KERN_CONT "cdrom or floppy?, assuming "); + if (drive->media != ide_cdrom) { + printk(KERN_CONT "FLOPPY"); + drive->dev_flags |= IDE_DFLAG_REMOVABLE; + break; + } + } + /* Early cdrom models used zero */ + type = ide_cdrom; + case ide_cdrom: + drive->dev_flags |= IDE_DFLAG_REMOVABLE; +#ifdef CONFIG_PPC + /* kludge for Apple PowerBook internal zip */ + if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) { + printk(KERN_CONT "FLOPPY"); + type = ide_floppy; + break; + } +#endif + printk(KERN_CONT "CD/DVD-ROM"); + break; + case ide_tape: + printk(KERN_CONT "TAPE"); + break; + case ide_optical: + printk(KERN_CONT "OPTICAL"); + drive->dev_flags |= IDE_DFLAG_REMOVABLE; + break; + default: + printk(KERN_CONT "UNKNOWN (type %d)", type); + break; + } + + printk(KERN_CONT " drive\n"); + drive->media = type; + /* an ATAPI device ignores DRDY */ + drive->ready_stat = 0; + if (ata_id_cdb_intr(id)) + drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; + drive->dev_flags |= IDE_DFLAG_DOORLOCKING; + /* we don't do head unloading on ATAPI devices */ + drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; +} + /** * do_identify - identify a drive * @drive: drive to identify @@ -117,7 +193,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd) u16 *id = drive->id; char *m = (char *)&id[ATA_ID_PROD]; unsigned long flags; - int bswap = 1, is_cfa; + int bswap = 1; /* local CPU only; some systems need this */ local_irq_save(flags); @@ -154,91 +230,23 @@ static void do_identify(ide_drive_t *drive, u8 cmd) if (strstr(m, "E X A B Y T E N E S T")) goto err_misc; - printk(KERN_INFO "%s: %s, ", drive->name, m); - drive->dev_flags |= IDE_DFLAG_PRESENT; drive->dev_flags &= ~IDE_DFLAG_DEAD; /* * Check for an ATAPI device */ - if (cmd == ATA_CMD_ID_ATAPI) { - u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f; - - printk(KERN_CONT "ATAPI "); - switch (type) { - case ide_floppy: - if (!strstr(m, "CD-ROM")) { - if (!strstr(m, "oppy") && - !strstr(m, "poyp") && - !strstr(m, "ZIP")) - printk(KERN_CONT "cdrom or floppy?, assuming "); - if (drive->media != ide_cdrom) { - printk(KERN_CONT "FLOPPY"); - drive->dev_flags |= IDE_DFLAG_REMOVABLE; - break; - } - } - /* Early cdrom models used zero */ - type = ide_cdrom; - case ide_cdrom: - drive->dev_flags |= IDE_DFLAG_REMOVABLE; -#ifdef CONFIG_PPC - /* kludge for Apple PowerBook internal zip */ - if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) { - printk(KERN_CONT "FLOPPY"); - type = ide_floppy; - break; - } -#endif - printk(KERN_CONT "CD/DVD-ROM"); - break; - case ide_tape: - printk(KERN_CONT "TAPE"); - break; - case ide_optical: - printk(KERN_CONT "OPTICAL"); - drive->dev_flags |= IDE_DFLAG_REMOVABLE; - break; - default: - printk(KERN_CONT "UNKNOWN (type %d)", type); - break; - } - printk(KERN_CONT " drive\n"); - drive->media = type; - /* an ATAPI device ignores DRDY */ - drive->ready_stat = 0; - if (ata_id_cdb_intr(id)) - drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; - drive->dev_flags |= IDE_DFLAG_DOORLOCKING; - /* we don't do head unloading on ATAPI devices */ - drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; - return; - } - + if (cmd == ATA_CMD_ID_ATAPI) + ide_classify_atapi_dev(drive); + else /* * Not an ATAPI device: looks like a "regular" hard disk */ - - is_cfa = ata_id_is_cfa(id); - - /* CF devices are *not* removable in Linux definition of the term */ - if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7))) - drive->dev_flags |= IDE_DFLAG_REMOVABLE; - - drive->media = ide_disk; - - if (!ata_id_has_unload(drive->id)) - drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; - - printk(KERN_CONT "%s DISK drive\n", is_cfa ? "CFA" : "ATA"); - + ide_classify_ata_dev(drive); return; - err_misc: kfree(id); drive->dev_flags &= ~IDE_DFLAG_PRESENT; - return; } /** -- cgit From ebdab07dad3d3a008e519b0a028e1e1ad5ecaef0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:48 +0100 Subject: ide: move sysfs support to ide-sysfs.c While at it: - media_string() -> ide_media_string() There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Makefile | 2 +- drivers/ide/ide-probe.c | 52 -------------------- drivers/ide/ide-sysfs.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/ide/ide.c | 72 +--------------------------- 4 files changed, 128 insertions(+), 123 deletions(-) create mode 100644 drivers/ide/ide-sysfs.c (limited to 'drivers/ide') diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 177e3f8523e..410728992e6 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -5,7 +5,7 @@ EXTRA_CFLAGS += -Idrivers/ide ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ - ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o + ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o # core IDE code ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 91f5faee740..f9efd069edc 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1420,58 +1420,6 @@ static void ide_port_cable_detect(ide_hwif_t *hwif) } } -static ssize_t store_delete_devices(struct device *portdev, - struct device_attribute *attr, - const char *buf, size_t n) -{ - ide_hwif_t *hwif = dev_get_drvdata(portdev); - - if (strncmp(buf, "1", n)) - return -EINVAL; - - ide_port_unregister_devices(hwif); - - return n; -}; - -static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices); - -static ssize_t store_scan(struct device *portdev, - struct device_attribute *attr, - const char *buf, size_t n) -{ - ide_hwif_t *hwif = dev_get_drvdata(portdev); - - if (strncmp(buf, "1", n)) - return -EINVAL; - - ide_port_unregister_devices(hwif); - ide_port_scan(hwif); - - return n; -}; - -static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan); - -static struct device_attribute *ide_port_attrs[] = { - &dev_attr_delete_devices, - &dev_attr_scan, - NULL -}; - -static int ide_sysfs_register_port(ide_hwif_t *hwif) -{ - int i, uninitialized_var(rc); - - for (i = 0; ide_port_attrs[i]; i++) { - rc = device_create_file(hwif->portdev, ide_port_attrs[i]); - if (rc) - break; - } - - return rc; -} - static unsigned int ide_indexes; /** diff --git a/drivers/ide/ide-sysfs.c b/drivers/ide/ide-sysfs.c new file mode 100644 index 00000000000..883ffacaf45 --- /dev/null +++ b/drivers/ide/ide-sysfs.c @@ -0,0 +1,125 @@ +#include +#include + +char *ide_media_string(ide_drive_t *drive) +{ + switch (drive->media) { + case ide_disk: + return "disk"; + case ide_cdrom: + return "cdrom"; + case ide_tape: + return "tape"; + case ide_floppy: + return "floppy"; + case ide_optical: + return "optical"; + default: + return "UNKNOWN"; + } +} + +static ssize_t media_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + ide_drive_t *drive = to_ide_device(dev); + return sprintf(buf, "%s\n", ide_media_string(drive)); +} + +static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + ide_drive_t *drive = to_ide_device(dev); + return sprintf(buf, "%s\n", drive->name); +} + +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + ide_drive_t *drive = to_ide_device(dev); + return sprintf(buf, "ide:m-%s\n", ide_media_string(drive)); +} + +static ssize_t model_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + ide_drive_t *drive = to_ide_device(dev); + return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]); +} + +static ssize_t firmware_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + ide_drive_t *drive = to_ide_device(dev); + return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]); +} + +static ssize_t serial_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + ide_drive_t *drive = to_ide_device(dev); + return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]); +} + +struct device_attribute ide_dev_attrs[] = { + __ATTR_RO(media), + __ATTR_RO(drivename), + __ATTR_RO(modalias), + __ATTR_RO(model), + __ATTR_RO(firmware), + __ATTR(serial, 0400, serial_show, NULL), + __ATTR(unload_heads, 0644, ide_park_show, ide_park_store), + __ATTR_NULL +}; + +static ssize_t store_delete_devices(struct device *portdev, + struct device_attribute *attr, + const char *buf, size_t n) +{ + ide_hwif_t *hwif = dev_get_drvdata(portdev); + + if (strncmp(buf, "1", n)) + return -EINVAL; + + ide_port_unregister_devices(hwif); + + return n; +}; + +static DEVICE_ATTR(delete_devices, S_IWUSR, NULL, store_delete_devices); + +static ssize_t store_scan(struct device *portdev, + struct device_attribute *attr, + const char *buf, size_t n) +{ + ide_hwif_t *hwif = dev_get_drvdata(portdev); + + if (strncmp(buf, "1", n)) + return -EINVAL; + + ide_port_unregister_devices(hwif); + ide_port_scan(hwif); + + return n; +}; + +static DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan); + +static struct device_attribute *ide_port_attrs[] = { + &dev_attr_delete_devices, + &dev_attr_scan, + NULL +}; + +int ide_sysfs_register_port(ide_hwif_t *hwif) +{ + int i, uninitialized_var(rc); + + for (i = 0; ide_port_attrs[i]; i++) { + rc = device_create_file(hwif->portdev, ide_port_attrs[i]); + if (rc) + break; + } + + return rc; +} diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index f0f09f702e9..46a2d4ca812 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -440,81 +440,13 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv) return 1; } -static char *media_string(ide_drive_t *drive) -{ - switch (drive->media) { - case ide_disk: - return "disk"; - case ide_cdrom: - return "cdrom"; - case ide_tape: - return "tape"; - case ide_floppy: - return "floppy"; - case ide_optical: - return "optical"; - default: - return "UNKNOWN"; - } -} - -static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - ide_drive_t *drive = to_ide_device(dev); - return sprintf(buf, "%s\n", media_string(drive)); -} - -static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - ide_drive_t *drive = to_ide_device(dev); - return sprintf(buf, "%s\n", drive->name); -} - -static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - ide_drive_t *drive = to_ide_device(dev); - return sprintf(buf, "ide:m-%s\n", media_string(drive)); -} - -static ssize_t model_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - ide_drive_t *drive = to_ide_device(dev); - return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]); -} - -static ssize_t firmware_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - ide_drive_t *drive = to_ide_device(dev); - return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]); -} - -static ssize_t serial_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - ide_drive_t *drive = to_ide_device(dev); - return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]); -} - -static struct device_attribute ide_dev_attrs[] = { - __ATTR_RO(media), - __ATTR_RO(drivename), - __ATTR_RO(modalias), - __ATTR_RO(model), - __ATTR_RO(firmware), - __ATTR(serial, 0400, serial_show, NULL), - __ATTR(unload_heads, 0644, ide_park_show, ide_park_store), - __ATTR_NULL -}; - static int ide_uevent(struct device *dev, struct kobj_uevent_env *env) { ide_drive_t *drive = to_ide_device(dev); - add_uevent_var(env, "MEDIA=%s", media_string(drive)); + add_uevent_var(env, "MEDIA=%s", ide_media_string(drive)); add_uevent_var(env, "DRIVENAME=%s", drive->name); - add_uevent_var(env, "MODALIAS=ide:m-%s", media_string(drive)); + add_uevent_var(env, "MODALIAS=ide:m-%s", ide_media_string(drive)); return 0; } -- cgit From 295f00042aaf6b553b5f37348f89bab463d4a469 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:48 +0100 Subject: ide: don't execute the next queued command from the hard-IRQ context (v2) * Tell the block layer that we are not done handling requests by using blk_plug_device() in ide_do_request() (request handling function) and ide_timer_expiry() (timeout handler) if the queue is not empty. * Remove optimization which directly calls ide_do_request() for the next queued command from the ide_intr() (IRQ handler) and ide_timer_expiry(). * Remove no longer needed IRQ masking from ide_do_request() - in case of IDE ports needing serialization disable_irq_nosync()/enable_irq() was used for the (possibly shared) IRQ of the other IDE port. * Put the misplaced comment in the right place in ide_do_request(). * Drop no longer needed 'int masked_irq' argument from ide_do_request(). * Merge ide_do_request() into do_ide_request(). * Remove no longer needed IDE_NO_IRQ define. While at it: * Don't use HWGROUP() macro in do_ide_request(). * Use __func__ in ide_intr(). This patch reduces IRQ hadling latency for IDE and improves the system-wide handling of shared IRQs (which should result in more timeout resistant and stable IDE systems). It also makes it possible to do some further changes later (i.e. replace some busy-waiting delays with sleeping equivalents). v2: Changes per review from Elias Oltmanns: - fix wrong goto statement in 'if (startstop == ide_stopped)' block - use spin_unlock_irq() - don't use obsolete HWIF() macro Cc: Elias Oltmanns Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 67 +++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 37 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ecacc008fda..23754bc5e59 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -778,8 +778,10 @@ repeat: * the driver. This makes the driver much more friendlier to shared IRQs * than previous designs, while remaining 100% (?) SMP safe and capable. */ -static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) +void do_ide_request(struct request_queue *q) { + ide_drive_t *orig_drive = q->queuedata; + ide_hwgroup_t *hwgroup = orig_drive->hwif->hwgroup; ide_drive_t *drive; ide_hwif_t *hwif; struct request *rq; @@ -837,10 +839,14 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) } /* no more work for this hwgroup (for now) */ - return; + goto plug_device; } - again: - hwif = HWIF(drive); + + if (drive != orig_drive) + goto plug_device; +again: + hwif = drive->hwif; + if (hwif != hwgroup->hwif) { /* * set nIEN for previous hwif, drives in the @@ -888,41 +894,26 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) goto again; /* We clear busy, there should be no pending ATA command at this point. */ hwgroup->busy = 0; - break; + goto plug_device; } hwgroup->rq = rq; - /* - * Some systems have trouble with IDE IRQs arriving while - * the driver is still setting things up. So, here we disable - * the IRQ used by this interface while the request is being started. - * This may look bad at first, but pretty much the same thing - * happens anyway when any interrupt comes in, IDE or otherwise - * -- the kernel masks the IRQ while it is being handled. - */ - if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) - disable_irq_nosync(hwif->irq); - spin_unlock(&hwgroup->lock); - local_irq_enable_in_hardirq(); - /* allow other IRQs while we start this request */ + spin_unlock_irq(&hwgroup->lock); startstop = start_request(drive, rq); spin_lock_irq(&hwgroup->lock); - if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) - enable_irq(hwif->irq); - if (startstop == ide_stopped) + + if (startstop == ide_stopped) { hwgroup->busy = 0; + if (!elv_queue_empty(orig_drive->queue)) + blk_plug_device(orig_drive->queue); + } } -} + return; -/* - * Passes the stuff to ide_do_request - */ -void do_ide_request(struct request_queue *q) -{ - ide_drive_t *drive = q->queuedata; - - ide_do_request(HWGROUP(drive), IDE_NO_IRQ); +plug_device: + if (!elv_queue_empty(orig_drive->queue)) + blk_plug_device(orig_drive->queue); } /* @@ -1074,11 +1065,13 @@ void ide_timer_expiry (unsigned long data) drive->service_time = jiffies - drive->service_start; spin_lock_irq(&hwgroup->lock); enable_irq(hwif->irq); - if (startstop == ide_stopped) + if (startstop == ide_stopped) { hwgroup->busy = 0; + if (!elv_queue_empty(drive->queue)) + blk_plug_device(drive->queue); + } } } - ide_do_request(hwgroup, IDE_NO_IRQ); spin_unlock_irqrestore(&hwgroup->lock, flags); } @@ -1271,11 +1264,11 @@ irqreturn_t ide_intr (int irq, void *dev_id) if (startstop == ide_stopped) { if (hwgroup->handler == NULL) { /* paranoia */ hwgroup->busy = 0; - ide_do_request(hwgroup, hwif->irq); - } else { - printk(KERN_ERR "%s: ide_intr: huh? expected NULL handler " - "on exit\n", drive->name); - } + if (!elv_queue_empty(drive->queue)) + blk_plug_device(drive->queue); + } else + printk(KERN_ERR "%s: %s: huh? expected NULL handler " + "on exit\n", __func__, drive->name); } out_handled: irq_ret = IRQ_HANDLED; -- cgit From 2fb211502e2c0513e12d677ed4d7891f3c5e1413 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:49 +0100 Subject: ide: remove IDE PM hack from do_ide_request() We now tell block layer that there is still work to do using blk_plug_device() so hack for IDE Power Management can be removed (it was buggy for hwgroups having more than 4 devices anyway). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 23754bc5e59..40327d1e6a9 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -786,7 +786,6 @@ void do_ide_request(struct request_queue *q) ide_hwif_t *hwif; struct request *rq; ide_startstop_t startstop; - int loops = 0; /* caller must own hwgroup->lock */ BUG_ON(!irqs_disabled()); @@ -844,7 +843,7 @@ void do_ide_request(struct request_queue *q) if (drive != orig_drive) goto plug_device; -again: + hwif = drive->hwif; if (hwif != hwgroup->hwif) { @@ -882,16 +881,10 @@ again: * though. I hope that doesn't happen too much, hopefully not * unless the subdriver triggers such a thing in its own PM * state machine. - * - * We count how many times we loop here to make sure we service - * all drives in the hwgroup without looping for ever */ if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && blk_pm_request(rq) == 0 && (rq->cmd_flags & REQ_PREEMPT) == 0) { - drive = drive->next ? drive->next : hwgroup->drive; - if (loops++ < 4 && !blk_queue_plugged(drive->queue)) - goto again; /* We clear busy, there should be no pending ATA command at this point. */ hwgroup->busy = 0; goto plug_device; -- cgit From b2cfb05a701809abee591265a198afa029d68bff Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:49 +0100 Subject: ide: remove "paranoia" checks for hwgroup->busy Remove "paranoia" checks for hwgroup->busy from ide_timer_expiry() and ide_intr(). This is a preparation for future changes. Cc: Michael Schmitz Cc: Geert Uytterhoeven Cc: Elias Oltmanns Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 40327d1e6a9..c60512196f6 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1011,10 +1011,7 @@ void ide_timer_expiry (unsigned long data) } else { ide_hwif_t *hwif; ide_startstop_t startstop = ide_stopped; - if (!hwgroup->busy) { - hwgroup->busy = 1; /* paranoia */ - printk(KERN_ERR "%s: ide_timer_expiry: hwgroup->busy was 0 ??\n", drive->name); - } + if ((expiry = hwgroup->expiry) != NULL) { /* continue */ if ((wait = expiry(drive)) > 0) { @@ -1227,10 +1224,6 @@ irqreturn_t ide_intr (int irq, void *dev_id) */ goto out; - if (!hwgroup->busy) { - hwgroup->busy = 1; /* paranoia */ - printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name); - } hwgroup->handler = NULL; hwgroup->req_gen++; del_timer(&hwgroup->timer); -- cgit From 631de3708d595d153e8a510a3608689290f4c0ed Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:50 +0100 Subject: ide: add ide_[un]lock_hwgroup() helpers Add ide_[un]lock_hwgroup() inline helpers for obtaining exclusive access to the given hwgroup and update the core code accordingly. [ This change besides making code saner results in more efficient use of ide_{get,release}_lock(). ] Cc: Michael Schmitz Cc: Geert Uytterhoeven Cc: Elias Oltmanns Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 32 +++++++++++--------------------- drivers/ide/ide-park.c | 2 +- 2 files changed, 12 insertions(+), 22 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index c60512196f6..ab480042757 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -790,10 +790,7 @@ void do_ide_request(struct request_queue *q) /* caller must own hwgroup->lock */ BUG_ON(!irqs_disabled()); - while (!hwgroup->busy) { - hwgroup->busy = 1; - /* for atari only */ - ide_get_lock(ide_intr, hwgroup); + while (!ide_lock_hwgroup(hwgroup)) { drive = choose_drive(hwgroup); if (drive == NULL) { int sleeping = 0; @@ -825,17 +822,10 @@ void do_ide_request(struct request_queue *q) hwgroup->sleeping = 1; hwgroup->req_gen_timer = hwgroup->req_gen; mod_timer(&hwgroup->timer, sleep); - /* we purposely leave hwgroup->busy==1 + /* we purposely leave hwgroup locked * while sleeping */ - } else { - /* Ugly, but how can we sleep for the lock - * otherwise? perhaps from tq_disk? - */ - - /* for atari only */ - ide_release_lock(); - hwgroup->busy = 0; - } + } else + ide_unlock_hwgroup(hwgroup); /* no more work for this hwgroup (for now) */ goto plug_device; @@ -865,7 +855,7 @@ void do_ide_request(struct request_queue *q) */ rq = elv_next_request(drive->queue); if (!rq) { - hwgroup->busy = 0; + ide_unlock_hwgroup(hwgroup); break; } @@ -885,8 +875,8 @@ void do_ide_request(struct request_queue *q) if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && blk_pm_request(rq) == 0 && (rq->cmd_flags & REQ_PREEMPT) == 0) { - /* We clear busy, there should be no pending ATA command at this point. */ - hwgroup->busy = 0; + /* there should be no pending command at this point */ + ide_unlock_hwgroup(hwgroup); goto plug_device; } @@ -897,7 +887,7 @@ void do_ide_request(struct request_queue *q) spin_lock_irq(&hwgroup->lock); if (startstop == ide_stopped) { - hwgroup->busy = 0; + ide_unlock_hwgroup(hwgroup); if (!elv_queue_empty(orig_drive->queue)) blk_plug_device(orig_drive->queue); } @@ -1001,7 +991,7 @@ void ide_timer_expiry (unsigned long data) */ if (hwgroup->sleeping) { hwgroup->sleeping = 0; - hwgroup->busy = 0; + ide_unlock_hwgroup(hwgroup); } } else { ide_drive_t *drive = hwgroup->drive; @@ -1056,7 +1046,7 @@ void ide_timer_expiry (unsigned long data) spin_lock_irq(&hwgroup->lock); enable_irq(hwif->irq); if (startstop == ide_stopped) { - hwgroup->busy = 0; + ide_unlock_hwgroup(hwgroup); if (!elv_queue_empty(drive->queue)) blk_plug_device(drive->queue); } @@ -1249,7 +1239,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) drive->service_time = jiffies - drive->service_start; if (startstop == ide_stopped) { if (hwgroup->handler == NULL) { /* paranoia */ - hwgroup->busy = 0; + ide_unlock_hwgroup(hwgroup); if (!elv_queue_empty(drive->queue)) blk_plug_device(drive->queue); } else diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 63d01c55f86..44c6787f8ae 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c @@ -22,7 +22,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) if (reset_timer && hwgroup->sleeping && del_timer(&hwgroup->timer)) { hwgroup->sleeping = 0; - hwgroup->busy = 0; + ide_unlock_hwgroup(hwgroup); blk_start_queueing(q); } spin_unlock_irq(&hwgroup->lock); -- cgit From 201bffa46466b4afdf7d29db8eca3fa5decb39c8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 2 Jan 2009 16:12:50 +0100 Subject: ide: use per-device request queue locks (v2) * Move hack for flush requests from choose_drive() to do_ide_request(). * Add ide_plug_device() helper and convert core IDE code from using per-hwgroup lock as a request lock to use the ->queue_lock instead. * Remove no longer needed: - choose_drive() function - WAKEUP() macro - 'sleeping' flag from ide_hwif_t - 'service_{start,time}' fields from ide_drive_t This patch results in much simpler and more maintainable code (besides being a scalability improvement). v2: * Fixes/improvements based on review from Elias: - take as many requests off the queue as possible - remove now redundant BUG_ON() Cc: Elias Oltmanns Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 214 +++++++++++++++--------------------------------- drivers/ide/ide-park.c | 13 +-- drivers/ide/ide-probe.c | 3 +- 3 files changed, 77 insertions(+), 153 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ab480042757..bb3248abf47 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -667,85 +667,10 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) drive->sleep = timeout + jiffies; drive->dev_flags |= IDE_DFLAG_SLEEPING; } - EXPORT_SYMBOL(ide_stall_queue); -#define WAKEUP(drive) ((drive)->service_start + 2 * (drive)->service_time) - -/** - * choose_drive - select a drive to service - * @hwgroup: hardware group to select on - * - * choose_drive() selects the next drive which will be serviced. - * This is necessary because the IDE layer can't issue commands - * to both drives on the same cable, unlike SCSI. - */ - -static inline ide_drive_t *choose_drive (ide_hwgroup_t *hwgroup) -{ - ide_drive_t *drive, *best; - -repeat: - best = NULL; - drive = hwgroup->drive; - - /* - * drive is doing pre-flush, ordered write, post-flush sequence. even - * though that is 3 requests, it must be seen as a single transaction. - * we must not preempt this drive until that is complete - */ - if (blk_queue_flushing(drive->queue)) { - /* - * small race where queue could get replugged during - * the 3-request flush cycle, just yank the plug since - * we want it to finish asap - */ - blk_remove_plug(drive->queue); - return drive; - } - - do { - u8 dev_s = !!(drive->dev_flags & IDE_DFLAG_SLEEPING); - u8 best_s = (best && !!(best->dev_flags & IDE_DFLAG_SLEEPING)); - - if ((dev_s == 0 || time_after_eq(jiffies, drive->sleep)) && - !elv_queue_empty(drive->queue)) { - if (best == NULL || - (dev_s && (best_s == 0 || time_before(drive->sleep, best->sleep))) || - (best_s == 0 && time_before(WAKEUP(drive), WAKEUP(best)))) { - if (!blk_queue_plugged(drive->queue)) - best = drive; - } - } - } while ((drive = drive->next) != hwgroup->drive); - - if (best && (best->dev_flags & IDE_DFLAG_NICE1) && - (best->dev_flags & IDE_DFLAG_SLEEPING) == 0 && - best != hwgroup->drive && best->service_time > WAIT_MIN_SLEEP) { - long t = (signed long)(WAKEUP(best) - jiffies); - if (t >= WAIT_MIN_SLEEP) { - /* - * We *may* have some time to spare, but first let's see if - * someone can potentially benefit from our nice mood today.. - */ - drive = best->next; - do { - if ((drive->dev_flags & IDE_DFLAG_SLEEPING) == 0 - && time_before(jiffies - best->service_time, WAKEUP(drive)) - && time_before(WAKEUP(drive), jiffies + t)) - { - ide_stall_queue(best, min_t(long, t, 10 * WAIT_MIN_SLEEP)); - goto repeat; - } - } while ((drive = drive->next) != best); - } - } - return best; -} - /* * Issue a new request to a drive from hwgroup - * Caller must have already done spin_lock_irqsave(&hwgroup->lock, ..); * * A hwgroup is a serialized group of IDE interfaces. Usually there is * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) @@ -757,8 +682,7 @@ repeat: * possibly along with many other devices. This is especially common in * PCI-based systems with off-board IDE controller cards. * - * The IDE driver uses a per-hwgroup spinlock to protect - * access to the request queues, and to protect the hwgroup->busy flag. + * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag. * * The first thread into the driver for a particular hwgroup sets the * hwgroup->busy flag to indicate that this hwgroup is now active, @@ -780,61 +704,38 @@ repeat: */ void do_ide_request(struct request_queue *q) { - ide_drive_t *orig_drive = q->queuedata; - ide_hwgroup_t *hwgroup = orig_drive->hwif->hwgroup; - ide_drive_t *drive; - ide_hwif_t *hwif; + ide_drive_t *drive = q->queuedata; + ide_hwif_t *hwif = drive->hwif; + ide_hwgroup_t *hwgroup = hwif->hwgroup; struct request *rq; ide_startstop_t startstop; - /* caller must own hwgroup->lock */ - BUG_ON(!irqs_disabled()); - - while (!ide_lock_hwgroup(hwgroup)) { - drive = choose_drive(hwgroup); - if (drive == NULL) { - int sleeping = 0; - unsigned long sleep = 0; /* shut up, gcc */ - hwgroup->rq = NULL; - drive = hwgroup->drive; - do { - if ((drive->dev_flags & IDE_DFLAG_SLEEPING) && - (sleeping == 0 || - time_before(drive->sleep, sleep))) { - sleeping = 1; - sleep = drive->sleep; - } - } while ((drive = drive->next) != hwgroup->drive); - if (sleeping) { + /* + * drive is doing pre-flush, ordered write, post-flush sequence. even + * though that is 3 requests, it must be seen as a single transaction. + * we must not preempt this drive until that is complete + */ + if (blk_queue_flushing(q)) /* - * Take a short snooze, and then wake up this hwgroup again. - * This gives other hwgroups on the same a chance to - * play fairly with us, just in case there are big differences - * in relative throughputs.. don't want to hog the cpu too much. + * small race where queue could get replugged during + * the 3-request flush cycle, just yank the plug since + * we want it to finish asap */ - if (time_before(sleep, jiffies + WAIT_MIN_SLEEP)) - sleep = jiffies + WAIT_MIN_SLEEP; -#if 1 - if (timer_pending(&hwgroup->timer)) - printk(KERN_CRIT "ide_set_handler: timer already active\n"); -#endif - /* so that ide_timer_expiry knows what to do */ - hwgroup->sleeping = 1; - hwgroup->req_gen_timer = hwgroup->req_gen; - mod_timer(&hwgroup->timer, sleep); - /* we purposely leave hwgroup locked - * while sleeping */ - } else - ide_unlock_hwgroup(hwgroup); + blk_remove_plug(q); - /* no more work for this hwgroup (for now) */ - goto plug_device; - } + spin_unlock_irq(q->queue_lock); + spin_lock_irq(&hwgroup->lock); - if (drive != orig_drive) - goto plug_device; + if (!ide_lock_hwgroup(hwgroup)) { +repeat: + hwgroup->rq = NULL; - hwif = drive->hwif; + if (drive->dev_flags & IDE_DFLAG_SLEEPING) { + if (time_before(drive->sleep, jiffies)) { + ide_unlock_hwgroup(hwgroup); + goto plug_device; + } + } if (hwif != hwgroup->hwif) { /* @@ -847,16 +748,20 @@ void do_ide_request(struct request_queue *q) hwgroup->hwif = hwif; hwgroup->drive = drive; drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); - drive->service_start = jiffies; + spin_unlock_irq(&hwgroup->lock); + spin_lock_irq(q->queue_lock); /* * we know that the queue isn't empty, but this can happen * if the q->prep_rq_fn() decides to kill a request */ rq = elv_next_request(drive->queue); + spin_unlock_irq(q->queue_lock); + spin_lock_irq(&hwgroup->lock); + if (!rq) { ide_unlock_hwgroup(hwgroup); - break; + goto out; } /* @@ -886,17 +791,21 @@ void do_ide_request(struct request_queue *q) startstop = start_request(drive, rq); spin_lock_irq(&hwgroup->lock); - if (startstop == ide_stopped) { - ide_unlock_hwgroup(hwgroup); - if (!elv_queue_empty(orig_drive->queue)) - blk_plug_device(orig_drive->queue); - } - } + if (startstop == ide_stopped) + goto repeat; + } else + goto plug_device; +out: + spin_unlock_irq(&hwgroup->lock); + spin_lock_irq(q->queue_lock); return; plug_device: - if (!elv_queue_empty(orig_drive->queue)) - blk_plug_device(orig_drive->queue); + spin_unlock_irq(&hwgroup->lock); + spin_lock_irq(q->queue_lock); + + if (!elv_queue_empty(q)) + blk_plug_device(q); } /* @@ -957,6 +866,17 @@ out: return ret; } +static void ide_plug_device(ide_drive_t *drive) +{ + struct request_queue *q = drive->queue; + unsigned long flags; + + spin_lock_irqsave(q->queue_lock, flags); + if (!elv_queue_empty(q)) + blk_plug_device(q); + spin_unlock_irqrestore(q->queue_lock, flags); +} + /** * ide_timer_expiry - handle lack of an IDE interrupt * @data: timer callback magic (hwgroup) @@ -974,10 +894,12 @@ out: void ide_timer_expiry (unsigned long data) { ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data; + ide_drive_t *uninitialized_var(drive); ide_handler_t *handler; ide_expiry_t *expiry; unsigned long flags; unsigned long wait = -1; + int plug_device = 0; spin_lock_irqsave(&hwgroup->lock, flags); @@ -989,12 +911,8 @@ void ide_timer_expiry (unsigned long data) * or we were "sleeping" to give other devices a chance. * Either way, we don't really want to complain about anything. */ - if (hwgroup->sleeping) { - hwgroup->sleeping = 0; - ide_unlock_hwgroup(hwgroup); - } } else { - ide_drive_t *drive = hwgroup->drive; + drive = hwgroup->drive; if (!drive) { printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n"); hwgroup->handler = NULL; @@ -1042,17 +960,18 @@ void ide_timer_expiry (unsigned long data) ide_error(drive, "irq timeout", hwif->tp_ops->read_status(hwif)); } - drive->service_time = jiffies - drive->service_start; spin_lock_irq(&hwgroup->lock); enable_irq(hwif->irq); if (startstop == ide_stopped) { ide_unlock_hwgroup(hwgroup); - if (!elv_queue_empty(drive->queue)) - blk_plug_device(drive->queue); + plug_device = 1; } } } spin_unlock_irqrestore(&hwgroup->lock, flags); + + if (plug_device) + ide_plug_device(drive); } /** @@ -1146,10 +1065,11 @@ irqreturn_t ide_intr (int irq, void *dev_id) unsigned long flags; ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; ide_hwif_t *hwif = hwgroup->hwif; - ide_drive_t *drive; + ide_drive_t *uninitialized_var(drive); ide_handler_t *handler; ide_startstop_t startstop; irqreturn_t irq_ret = IRQ_NONE; + int plug_device = 0; spin_lock_irqsave(&hwgroup->lock, flags); @@ -1236,12 +1156,10 @@ irqreturn_t ide_intr (int irq, void *dev_id) * same irq as is currently being serviced here, and Linux * won't allow another of the same (on any CPU) until we return. */ - drive->service_time = jiffies - drive->service_start; if (startstop == ide_stopped) { if (hwgroup->handler == NULL) { /* paranoia */ ide_unlock_hwgroup(hwgroup); - if (!elv_queue_empty(drive->queue)) - blk_plug_device(drive->queue); + plug_device = 1; } else printk(KERN_ERR "%s: %s: huh? expected NULL handler " "on exit\n", __func__, drive->name); @@ -1250,6 +1168,10 @@ out_handled: irq_ret = IRQ_HANDLED; out: spin_unlock_irqrestore(&hwgroup->lock, flags); + + if (plug_device) + ide_plug_device(drive); + return irq_ret; } diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 44c6787f8ae..678454ac248 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c @@ -16,16 +16,19 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) spin_lock_irq(&hwgroup->lock); if (drive->dev_flags & IDE_DFLAG_PARKED) { int reset_timer = time_before(timeout, drive->sleep); + int start_queue = 0; drive->sleep = timeout; wake_up_all(&ide_park_wq); - if (reset_timer && hwgroup->sleeping && - del_timer(&hwgroup->timer)) { - hwgroup->sleeping = 0; - ide_unlock_hwgroup(hwgroup); + if (reset_timer && del_timer(&hwgroup->timer)) + start_queue = 1; + spin_unlock_irq(&hwgroup->lock); + + if (start_queue) { + spin_lock_irq(q->queue_lock); blk_start_queueing(q); + spin_unlock_irq(q->queue_lock); } - spin_unlock_irq(&hwgroup->lock); return; } spin_unlock_irq(&hwgroup->lock); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index f9efd069edc..966b74c1577 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -881,8 +881,7 @@ static int ide_init_queue(ide_drive_t *drive) * do not. */ - q = blk_init_queue_node(do_ide_request, &hwif->hwgroup->lock, - hwif_to_node(hwif)); + q = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif)); if (!q) return 1; -- cgit From 0f38aaa4980fdf5de215e0a8bf6d6032164a6c4b Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:50 +0100 Subject: ide-cd: move debug defines into header While at it: - disable compiling-in debug support by default Signed-off-by: Borislav Petkov [bart: fixup patch description] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 8 -------- drivers/ide/ide-cd.h | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 5daa4dd1b01..65e5513758b 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -53,14 +53,6 @@ #include "ide-cd.h" -#define IDECD_DEBUG_LOG 1 - -#if IDECD_DEBUG_LOG -#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) -#else -#define ide_debug_log(lvl, fmt, args...) do {} while (0) -#endif - static DEFINE_MUTEX(idecd_ref_mutex); static void ide_cd_release(struct kref *); diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index d5ce3362dbd..389faa42eaa 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -8,6 +8,14 @@ #include #include +#define IDECD_DEBUG_LOG 0 + +#if IDECD_DEBUG_LOG +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) +#else +#define ide_debug_log(lvl, fmt, args...) do {} while (0) +#endif + /* * typical timeout for packet command */ -- cgit From 07bd3f4731f9c7ebcbab90905ca4ad6fc6825f96 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 2 Jan 2009 16:12:51 +0100 Subject: ide-floppy: allocate only toplevel packet commands This makes the top-level function just allocate a single pc entry, and then pass it down as a pointer to all the helper functions that also need one of those "struct ide_atapi_pc" things. As far as I can tell, the use of these things never overlaps each other, BUT I DID NOT CHECK VERY CLOSELY! So I'm not guaranteeing this is correct, and I don't have the hardware. It would be good for somebody who knows the code more, and has the hardware, could please test this? With this, ide-floppy still has fairly big stack usage, but instead of idefloppy_ioctl [vmlinux]: 1208 ide_floppy_get_capacity [vmlinux]: 872 idefloppy_release [vmlinux]: 408 idefloppy_open [vmlinux]: 408 where those two first ones are at the very top of the list of stack users for me, it's now ide_floppy_get_capacity [vmlinux]: 404 ide_floppy_ioctl [vmlinux]: 364 ie they are still high, but they are no longer at the top. Borislav: Since ide_floppy_get_capacity is passed as a function pointer to other parts of the kernel (e.g., block layer) we need that ide_atapi_pc to be created on stack. Also, redid stack users numbers above. The two functions missing from Linus' original 'make stackusage' output are due to ide being rewritten/reorganized atm. Signed-off-by: Linus Torvalds Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-floppy.c | 26 +++++++++---------- drivers/ide/ide-floppy_ioctl.c | 58 ++++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 41 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index aeb1ad782f5..1f07f381893 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -342,38 +342,38 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, * Look at the flexible disk page parameters. We ignore the CHS capacity * parameters and use the LBA parameters instead. */ -static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) +static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive, + struct ide_atapi_pc *pc) { struct ide_disk_obj *floppy = drive->driver_data; struct gendisk *disk = floppy->disk; - struct ide_atapi_pc pc; u8 *page; int capacity, lba_capacity; u16 transfer_rate, sector_size, cyls, rpm; u8 heads, sectors; - ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); + ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); - if (ide_queue_pc_tail(drive, disk, &pc)) { + if (ide_queue_pc_tail(drive, disk, pc)) { printk(KERN_ERR PFX "Can't get flexible disk page params\n"); return 1; } - if (pc.buf[3] & 0x80) + if (pc->buf[3] & 0x80) drive->dev_flags |= IDE_DFLAG_WP; else drive->dev_flags &= ~IDE_DFLAG_WP; set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); - page = &pc.buf[8]; + page = &pc->buf[8]; - transfer_rate = be16_to_cpup((__be16 *)&pc.buf[8 + 2]); - sector_size = be16_to_cpup((__be16 *)&pc.buf[8 + 6]); - cyls = be16_to_cpup((__be16 *)&pc.buf[8 + 8]); - rpm = be16_to_cpup((__be16 *)&pc.buf[8 + 28]); - heads = pc.buf[8 + 4]; - sectors = pc.buf[8 + 5]; + transfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]); + sector_size = be16_to_cpup((__be16 *)&pc->buf[8 + 6]); + cyls = be16_to_cpup((__be16 *)&pc->buf[8 + 8]); + rpm = be16_to_cpup((__be16 *)&pc->buf[8 + 28]); + heads = pc->buf[8 + 4]; + sectors = pc->buf[8 + 5]; capacity = cyls * heads * sectors * sector_size; @@ -499,7 +499,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) /* Clik! disk does not support get_flexible_disk_page */ if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) - (void) ide_floppy_get_flexible_disk_page(drive); + (void) ide_floppy_get_flexible_disk_page(drive, &pc); return rc; } diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c index 2bc51ff73fe..8f8be854603 100644 --- a/drivers/ide/ide-floppy_ioctl.c +++ b/drivers/ide/ide-floppy_ioctl.c @@ -31,10 +31,11 @@ * On exit we set nformats to the number of records we've actually initialized. */ -static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) +static int ide_floppy_get_format_capacities(ide_drive_t *drive, + struct ide_atapi_pc *pc, + int __user *arg) { struct ide_disk_obj *floppy = drive->driver_data; - struct ide_atapi_pc pc; u8 header_len, desc_cnt; int i, blocks, length, u_array_size, u_index; int __user *argp; @@ -45,13 +46,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) if (u_array_size <= 0) return -EINVAL; - ide_floppy_create_read_capacity_cmd(&pc); - if (ide_queue_pc_tail(drive, floppy->disk, &pc)) { + ide_floppy_create_read_capacity_cmd(pc); + if (ide_queue_pc_tail(drive, floppy->disk, pc)) { printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); return -EIO; } - header_len = pc.buf[3]; + header_len = pc->buf[3]; desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ u_index = 0; @@ -68,8 +69,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) if (u_index >= u_array_size) break; /* User-supplied buffer too small */ - blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); - length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); + blocks = be32_to_cpup((__be32 *)&pc->buf[desc_start]); + length = be16_to_cpup((__be16 *)&pc->buf[desc_start + 6]); if (put_user(blocks, argp)) return -EFAULT; @@ -111,29 +112,28 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, pc->flags |= PC_FLAG_WRITING; } -static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) +static int ide_floppy_get_sfrp_bit(ide_drive_t *drive, struct ide_atapi_pc *pc) { struct ide_disk_obj *floppy = drive->driver_data; - struct ide_atapi_pc pc; drive->atapi_flags &= ~IDE_AFLAG_SRFP; - ide_floppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE); - pc.flags |= PC_FLAG_SUPPRESS_ERROR; + ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_CAPABILITIES_PAGE); + pc->flags |= PC_FLAG_SUPPRESS_ERROR; - if (ide_queue_pc_tail(drive, floppy->disk, &pc)) + if (ide_queue_pc_tail(drive, floppy->disk, pc)) return 1; - if (pc.buf[8 + 2] & 0x40) + if (pc->buf[8 + 2] & 0x40) drive->atapi_flags |= IDE_AFLAG_SRFP; return 0; } -static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) +static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc, + int __user *arg) { struct ide_disk_obj *floppy = drive->driver_data; - struct ide_atapi_pc pc; int blocks, length, flags, err = 0; if (floppy->openers > 1) { @@ -166,10 +166,10 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) goto out; } - (void)ide_floppy_get_sfrp_bit(drive); - ide_floppy_create_format_unit_cmd(&pc, blocks, length, flags); + ide_floppy_get_sfrp_bit(drive, pc); + ide_floppy_create_format_unit_cmd(pc, blocks, length, flags); - if (ide_queue_pc_tail(drive, floppy->disk, &pc)) + if (ide_queue_pc_tail(drive, floppy->disk, pc)) err = -EIO; out: @@ -188,15 +188,16 @@ out: * the dsc bit, and return either 0 or 65536. */ -static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) +static int ide_floppy_get_format_progress(ide_drive_t *drive, + struct ide_atapi_pc *pc, + int __user *arg) { struct ide_disk_obj *floppy = drive->driver_data; - struct ide_atapi_pc pc; int progress_indication = 0x10000; if (drive->atapi_flags & IDE_AFLAG_SRFP) { - ide_create_request_sense_cmd(drive, &pc); - if (ide_queue_pc_tail(drive, floppy->disk, &pc)) + ide_create_request_sense_cmd(drive, pc); + if (ide_queue_pc_tail(drive, floppy->disk, pc)) return -EIO; if (floppy->sense_key == 2 && @@ -241,20 +242,21 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, return 0; } -static int ide_floppy_format_ioctl(ide_drive_t *drive, fmode_t mode, - unsigned int cmd, void __user *argp) +static int ide_floppy_format_ioctl(ide_drive_t *drive, struct ide_atapi_pc *pc, + fmode_t mode, unsigned int cmd, + void __user *argp) { switch (cmd) { case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED: return 0; case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY: - return ide_floppy_get_format_capacities(drive, argp); + return ide_floppy_get_format_capacities(drive, pc, argp); case IDEFLOPPY_IOCTL_FORMAT_START: if (!(mode & FMODE_WRITE)) return -EPERM; - return ide_floppy_format_unit(drive, (int __user *)argp); + return ide_floppy_format_unit(drive, pc, (int __user *)argp); case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: - return ide_floppy_get_format_progress(drive, argp); + return ide_floppy_get_format_progress(drive, pc, argp); default: return -ENOTTY; } @@ -270,7 +272,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev, if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) return ide_floppy_lockdoor(drive, &pc, arg, cmd); - err = ide_floppy_format_ioctl(drive, mode, cmd, argp); + err = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp); if (err != -ENOTTY) return err; -- cgit From 93c164af19f608c5f737eb9bed8cb4de3a872329 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 2 Jan 2009 16:12:51 +0100 Subject: remove ide-scsi As planed, this removes ide-scsi. The 2.6 kernel supports direct writing to ide CD drives, which eliminates the need for ide-scsi. ide-scsi has been unmaintained and marked as deprecated. Signed-off-by: FUJITA Tomonori Cc: James.Bottomley@HansenPartnership.com Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Kconfig | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index c9f21e3d4ea..937945e471d 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -185,23 +185,6 @@ config BLK_DEV_IDETAPE To compile this driver as a module, choose M here: the module will be called ide-tape. -config BLK_DEV_IDESCSI - tristate "SCSI emulation support (DEPRECATED)" - depends on SCSI - select IDE_ATAPI - ---help--- - WARNING: ide-scsi is no longer needed for cd writing applications! - The 2.6 kernel supports direct writing to ide-cd, which eliminates - the need for ide-scsi + the entire scsi stack just for writing a - cd. The new method is more efficient in every way. - - This will provide SCSI host adapter emulation for IDE ATAPI devices, - and will allow you to use a SCSI device driver instead of a native - ATAPI driver. - - If both this SCSI emulation and native ATAPI support are compiled - into the kernel, the native support will be used. - config BLK_DEV_IDEACPI bool "IDE ACPI support" depends on ACPI -- cgit From 991cb26a6ad287c3bc6555c41e830590a23910c4 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:52 +0100 Subject: ide-atapi: add a dev_is_idecd-inline There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 4e58b9e7a58..33a15343e8b 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -14,6 +14,12 @@ #define debug_log(fmt, args...) do {} while (0) #endif +static inline int dev_is_idecd(ide_drive_t *drive) +{ + return (drive->media == ide_cdrom || drive->media == ide_optical) && + !(drive->dev_flags & IDE_DFLAG_SCSI); +} + /* * Check whether we can support a device, * based on the ATAPI IDENTIFY command results. @@ -577,7 +583,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, if (scsi) tf_flags = 0; - else if (drive->media == ide_cdrom || drive->media == ide_optical) + else if (dev_is_idecd(drive)) tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; else tf_flags = IDE_TFLAG_OUT_DEVICE; -- cgit From ed48554fad7091b9613b967462f082bf1a9cb035 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:52 +0100 Subject: ide-atapi: combine drive-specific assignments There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 33a15343e8b..b6e0aac6893 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -551,18 +551,24 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; u32 tf_flags; - u16 bcount; + u16 bcount = 0; u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI); /* We haven't transferred any data yet */ pc->xferred = 0; pc->cur_pos = pc->buf; - /* Request to transfer the entire buffer at once */ - if (drive->media == ide_tape && scsi == 0) - bcount = pc->req_xfer; - else + if (dev_is_idecd(drive)) { + tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; + } else if (scsi) { + tf_flags = 0; bcount = min(pc->req_xfer, 63 * 1024); + } else { + tf_flags = IDE_TFLAG_OUT_DEVICE; + bcount = ((drive->media == ide_tape) ? + pc->req_xfer : + min(pc->req_xfer, 63 * 1024)); + } if (pc->flags & PC_FLAG_DMA_ERROR) { pc->flags &= ~PC_FLAG_DMA_ERROR; @@ -581,13 +587,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, if (!drive->dma) pc->flags &= ~PC_FLAG_DMA_OK; - if (scsi) - tf_flags = 0; - else if (dev_is_idecd(drive)) - tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; - else - tf_flags = IDE_TFLAG_OUT_DEVICE; - ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); /* Issue the packet command */ -- cgit From 4f02ff06b4d33aba50ce5157c23e99cd21d447ee Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:52 +0100 Subject: ide-atapi: setup dma for ide-cd There should be no functional change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index b6e0aac6893..74273fdc882 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -575,8 +575,9 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, ide_dma_off(drive); } - if ((pc->flags & PC_FLAG_DMA_OK) && - (drive->dev_flags & IDE_DFLAG_USING_DMA)) { + if (((pc->flags & PC_FLAG_DMA_OK) && + (drive->dev_flags & IDE_DFLAG_USING_DMA)) || + drive->dma) { if (scsi) hwif->sg_mapped = 1; drive->dma = !hwif->dma_ops->dma_setup(drive); -- cgit From 392de1d53dd40e2eebee3a0a26aa647a3865ca78 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:52 +0100 Subject: ide-atapi: accomodate transfer length calculation for ide-cd ... by factoring it out of ide_cd_do_request() into a helper, as suggested by Bart. There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov [bart: BLK_DEV_IDECD needs to select IDE_ATAPI now] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Kconfig | 1 + drivers/ide/ide-atapi.c | 15 ++++++++++++++- drivers/ide/ide-cd.c | 4 ++-- 3 files changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 937945e471d..4ee85fcf9aa 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -137,6 +137,7 @@ config BLK_DEV_DELKIN config BLK_DEV_IDECD tristate "Include IDE/ATAPI CDROM support" + select IDE_ATAPI ---help--- If you have a CD-ROM drive using the ATAPI protocol, say Y. ATAPI is a newer protocol used by IDE CD-ROM and TAPE drives, similar to the diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 74273fdc882..8884877bd2b 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -252,6 +252,18 @@ int ide_scsi_expiry(ide_drive_t *drive) } EXPORT_SYMBOL_GPL(ide_scsi_expiry); +int ide_cd_get_xferlen(struct request *rq) +{ + if (blk_fs_request(rq)) + return 32768; + else if (blk_sense_request(rq) || blk_pc_request(rq) || + rq->cmd_type == REQ_TYPE_ATA_PC) + return rq->data_len; + else + return 0; +} +EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); + /* * This is the usual interrupt handler which will be called during a packet * command. We will transfer some of the data (as requested by the drive) @@ -551,7 +563,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; u32 tf_flags; - u16 bcount = 0; + u16 bcount; u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI); /* We haven't transferred any data yet */ @@ -560,6 +572,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, if (dev_is_idecd(drive)) { tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; + bcount = ide_cd_get_xferlen(hwif->hwgroup->rq); } else if (scsi) { tf_flags = 0; bcount = min(pc->req_xfer, 63 * 1024); diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 65e5513758b..8d3c7714682 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1214,8 +1214,9 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, __func__, rq->cmd[0], rq->cmd_type, (unsigned long long)block); + xferlen = ide_cd_get_xferlen(rq); + if (blk_fs_request(rq)) { - xferlen = 32768; fn = cdrom_start_rw_cont; if (cdrom_start_rw(drive, rq) == ide_stopped) @@ -1225,7 +1226,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, return ide_stopped; } else if (blk_sense_request(rq) || blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { - xferlen = rq->data_len; fn = cdrom_do_newpc_cont; if (!rq->timeout) -- cgit From 5f25843fa79b7c35097b0ffe8b2c5cc2428d6495 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:53 +0100 Subject: ide-atapi: teach ide atapi about drive->waiting_for_dma In addition, we wait for DRQ to be asserted by repeatedly polling device status no matter what DRQ type each device implements. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 8884877bd2b..8c5cf68fbd7 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -511,6 +511,11 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) return startstop; } + if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { + if (drive->dma) + drive->waiting_for_dma = 1; + } + ireason = ide_read_ireason(drive); if (drive->media == ide_tape && (drive->dev_flags & IDE_DFLAG_SCSI) == 0) @@ -605,6 +610,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, /* Issue the packet command */ if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { + if (drive->dma) + drive->waiting_for_dma = 0; ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, timeout, NULL); return ide_started; -- cgit From 4cad085efbce8dcc5006b0d1034089758b4fc7ba Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:53 +0100 Subject: ide-cd: move cdrom_timer_expiry to ide-atapi.c - cdrom_timer_expiry -> ide_cd_expiry - remove expiry-arg to ide_issue_pc as it is redundant now - ide_debug_log -> debug_log Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 41 ++++++++++++++++++++++++++++++++++++++--- drivers/ide/ide-cd.c | 38 +++----------------------------------- drivers/ide/ide-cd.h | 4 ---- drivers/ide/ide-floppy.c | 2 +- drivers/ide/ide-tape.c | 2 +- 5 files changed, 43 insertions(+), 44 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 8c5cf68fbd7..c110329ccb1 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include @@ -252,6 +253,38 @@ int ide_scsi_expiry(ide_drive_t *drive) } EXPORT_SYMBOL_GPL(ide_scsi_expiry); +int ide_cd_expiry(ide_drive_t *drive) +{ + struct request *rq = HWGROUP(drive)->rq; + unsigned long wait = 0; + + debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]); + + /* + * Some commands are *slow* and normally take a long time to complete. + * Usually we can use the ATAPI "disconnect" to bypass this, but not all + * commands/drives support that. Let ide_timer_expiry keep polling us + * for these. + */ + switch (rq->cmd[0]) { + case GPCMD_BLANK: + case GPCMD_FORMAT_UNIT: + case GPCMD_RESERVE_RZONE_TRACK: + case GPCMD_CLOSE_TRACK: + case GPCMD_FLUSH_CACHE: + wait = ATAPI_WAIT_PC; + break; + default: + if (!(rq->cmd_flags & REQ_QUIET)) + printk(KERN_INFO "cmd 0x%x timed out\n", + rq->cmd[0]); + wait = 0; + break; + } + return wait; +} +EXPORT_SYMBOL_GPL(ide_cd_expiry); + int ide_cd_get_xferlen(struct request *rq) { if (blk_fs_request(rq)) @@ -562,11 +595,11 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) return ide_started; } -ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, - ide_expiry_t *expiry) +ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout) { struct ide_atapi_pc *pc = drive->pc; ide_hwif_t *hwif = drive->hwif; + ide_expiry_t *expiry = NULL; u32 tf_flags; u16 bcount; u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI); @@ -578,9 +611,11 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, if (dev_is_idecd(drive)) { tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; bcount = ide_cd_get_xferlen(hwif->hwgroup->rq); + expiry = ide_cd_expiry; } else if (scsi) { tf_flags = 0; bcount = min(pc->req_xfer, 63 * 1024); + expiry = ide_scsi_expiry; } else { tf_flags = IDE_TFLAG_OUT_DEVICE; bcount = ((drive->media == ide_tape) ? @@ -613,7 +648,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout, if (drive->dma) drive->waiting_for_dma = 0; ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc, - timeout, NULL); + timeout, expiry); return ide_started; } else { ide_execute_pkt_cmd(drive); diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 8d3c7714682..105e4d855e6 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -511,38 +511,6 @@ end_request: return 1; } -static int cdrom_timer_expiry(ide_drive_t *drive) -{ - struct request *rq = HWGROUP(drive)->rq; - unsigned long wait = 0; - - ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd[0]: 0x%x\n", __func__, - rq->cmd[0]); - - /* - * Some commands are *slow* and normally take a long time to complete. - * Usually we can use the ATAPI "disconnect" to bypass this, but not all - * commands/drives support that. Let ide_timer_expiry keep polling us - * for these. - */ - switch (rq->cmd[0]) { - case GPCMD_BLANK: - case GPCMD_FORMAT_UNIT: - case GPCMD_RESERVE_RZONE_TRACK: - case GPCMD_CLOSE_TRACK: - case GPCMD_FLUSH_CACHE: - wait = ATAPI_WAIT_PC; - break; - default: - if (!(rq->cmd_flags & REQ_QUIET)) - printk(KERN_INFO PFX "cmd 0x%x timed out\n", - rq->cmd[0]); - wait = 0; - break; - } - return wait; -} - /* * Set up the device registers for transferring a packet command on DEV, * expecting to later transfer XFERLEN bytes. HANDLER is the routine @@ -574,7 +542,7 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, /* packet command */ ide_execute_command(drive, ATA_CMD_PACKET, handler, - ATAPI_WAIT_PC, cdrom_timer_expiry); + ATAPI_WAIT_PC, ide_cd_expiry); return ide_started; } else { ide_execute_pkt_cmd(drive); @@ -621,7 +589,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, } /* arm the interrupt handler */ - ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry); + ide_set_handler(drive, handler, rq->timeout, ide_cd_expiry); /* ATAPI commands get padded out to 12 bytes minimum */ cmd_len = COMMAND_SIZE(rq->cmd[0]); @@ -1088,7 +1056,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) } else { timeout = ATAPI_WAIT_PC; if (!blk_fs_request(rq)) - expiry = cdrom_timer_expiry; + expiry = ide_cd_expiry; } ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry); diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 389faa42eaa..bf676b26218 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -16,10 +16,6 @@ #define ide_debug_log(lvl, fmt, args...) do {} while (0) #endif -/* - * typical timeout for packet command - */ -#define ATAPI_WAIT_PC (60 * HZ) #define ATAPI_WAIT_WRITE_BUSY (10 * HZ) /************************************************************************/ diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 1f07f381893..fdec729d0e4 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -197,7 +197,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, pc->retries++; - return ide_issue_pc(drive, WAIT_FLOPPY_CMD, NULL); + return ide_issue_pc(drive, WAIT_FLOPPY_CMD); } void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index a2d470eb2b5..ac9e29a4991 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -694,7 +694,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, pc->retries++; - return ide_issue_pc(drive, WAIT_TAPE_CMD, NULL); + return ide_issue_pc(drive, WAIT_TAPE_CMD); } /* A mode sense command is used to "sense" tape parameters. */ -- cgit From 152fe1cc38ebebb81724663e3b1e1e10272a729e Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:53 +0100 Subject: ide-atapi: remove ide-scsi remnants from ide_issue_pc Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index c110329ccb1..ff6b567c019 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -602,7 +602,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout) ide_expiry_t *expiry = NULL; u32 tf_flags; u16 bcount; - u8 scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI); /* We haven't transferred any data yet */ pc->xferred = 0; @@ -612,10 +611,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout) tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; bcount = ide_cd_get_xferlen(hwif->hwgroup->rq); expiry = ide_cd_expiry; - } else if (scsi) { - tf_flags = 0; - bcount = min(pc->req_xfer, 63 * 1024); - expiry = ide_scsi_expiry; } else { tf_flags = IDE_TFLAG_OUT_DEVICE; bcount = ((drive->media == ide_tape) ? @@ -630,13 +625,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout) if (((pc->flags & PC_FLAG_DMA_OK) && (drive->dev_flags & IDE_DFLAG_USING_DMA)) || - drive->dma) { - if (scsi) - hwif->sg_mapped = 1; + drive->dma) drive->dma = !hwif->dma_ops->dma_setup(drive); - if (scsi) - hwif->sg_mapped = 0; - } if (!drive->dma) pc->flags &= ~PC_FLAG_DMA_OK; -- cgit From 5fe3110431ccf437607bdc11ac3677bf3eeee6e3 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:53 +0100 Subject: ide-atapi: remove ide-scsi remnants from ide_transfer_pc() Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index ff6b567c019..f5bf405c36a 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -550,8 +550,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) } ireason = ide_read_ireason(drive); - if (drive->media == ide_tape && - (drive->dev_flags & IDE_DFLAG_SCSI) == 0) + if (drive->media == ide_tape) ireason = ide_wait_ireason(drive, ireason); if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { @@ -569,14 +568,9 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) timeout = drive->pc_delay; expiry = &ide_delayed_transfer_pc; } else { - if (drive->dev_flags & IDE_DFLAG_SCSI) { - timeout = ide_scsi_get_timeout(pc); - expiry = ide_scsi_expiry; - } else { - timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD - : WAIT_TAPE_CMD; - expiry = NULL; - } + timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD + : WAIT_TAPE_CMD; + expiry = NULL; } /* Set the interrupt routine */ -- cgit From 5d655a03b847fbe5353a8a74bbeb75e18708dca3 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:54 +0100 Subject: ide-atapi: remove ide-scsi remnants from ide_pc_intr() As a result, remove now unused ide_scsi_get_timeout and ide_scsi_expiry. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 68 ++++++++++--------------------------------------- 1 file changed, 13 insertions(+), 55 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index f5bf405c36a..7a04509bf96 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -240,19 +240,6 @@ void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) } EXPORT_SYMBOL_GPL(ide_retry_pc); -int ide_scsi_expiry(ide_drive_t *drive) -{ - struct ide_atapi_pc *pc = drive->pc; - - debug_log("%s called for %lu at %lu\n", __func__, - pc->scsi_cmd->serial_number, jiffies); - - pc->flags |= PC_FLAG_TIMEDOUT; - - return 0; /* we do not want the IDE subsystem to retry */ -} -EXPORT_SYMBOL_GPL(ide_scsi_expiry); - int ide_cd_expiry(ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; @@ -309,21 +296,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) struct request *rq = hwif->hwgroup->rq; const struct ide_tp_ops *tp_ops = hwif->tp_ops; xfer_func_t *xferfunc; - ide_expiry_t *expiry; unsigned int timeout, temp; u16 bcount; - u8 stat, ireason, scsi = !!(drive->dev_flags & IDE_DFLAG_SCSI), dsc = 0; + u8 stat, ireason, dsc = 0; debug_log("Enter %s - interrupt handler\n", __func__); - if (scsi) { - timeout = ide_scsi_get_timeout(pc); - expiry = ide_scsi_expiry; - } else { - timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD - : WAIT_TAPE_CMD; - expiry = NULL; - } + timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD + : WAIT_TAPE_CMD; if (pc->flags & PC_FLAG_TIMEDOUT) { drive->pc_callback(drive, 0); @@ -335,8 +315,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { if (hwif->dma_ops->dma_end(drive) || - (drive->media == ide_tape && !scsi && (stat & ATA_ERR))) { - if (drive->media == ide_floppy && !scsi) + (drive->media == ide_tape && (stat & ATA_ERR))) { + if (drive->media == ide_floppy) printk(KERN_ERR "%s: DMA %s error\n", drive->name, rq_data_dir(pc->rq) ? "write" : "read"); @@ -358,7 +338,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) local_irq_enable_in_hardirq(); - if (drive->media == ide_tape && !scsi && + if (drive->media == ide_tape && (stat & ATA_ERR) && rq->cmd[0] == REQUEST_SENSE) stat &= ~ATA_ERR; @@ -366,11 +346,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) /* Error detected */ debug_log("%s: I/O error\n", drive->name); - if (drive->media != ide_tape || scsi) { + if (drive->media != ide_tape) pc->rq->errors++; - if (scsi) - goto cmd_finished; - } if (rq->cmd[0] == REQUEST_SENSE) { printk(KERN_ERR "%s: I/O error in request sense" @@ -386,7 +363,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) /* queued, but not started */ return ide_stopped; } -cmd_finished: pc->error = 0; if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) @@ -433,25 +409,8 @@ cmd_finished: "us more data than expected - " "discarding data\n", drive->name); - if (scsi) - temp = pc->buf_size - pc->xferred; - else - temp = 0; - if (temp) { - if (pc->sg) - drive->pc_io_buffers(drive, pc, - temp, 0); - else - tp_ops->input_data(drive, NULL, - pc->cur_pos, temp); - printk(KERN_ERR "%s: transferred %d of " - "%d bytes\n", - drive->name, - temp, bcount); - } - pc->xferred += temp; - pc->cur_pos += temp; - ide_pad_transfer(drive, 0, bcount - temp); + + ide_pad_transfer(drive, 0, bcount); goto next_irq; } debug_log("The device wants to send us more data than " @@ -461,14 +420,13 @@ cmd_finished: } else xferfunc = tp_ops->output_data; - if ((drive->media == ide_floppy && !scsi && !pc->buf) || - (drive->media == ide_tape && !scsi && pc->bh) || - (scsi && pc->sg)) { + if ((drive->media == ide_floppy && !pc->buf) || + (drive->media == ide_tape && pc->bh)) { int done = drive->pc_io_buffers(drive, pc, bcount, !!(pc->flags & PC_FLAG_WRITING)); /* FIXME: don't do partial completions */ - if (drive->media == ide_floppy && !scsi) + if (drive->media == ide_floppy) ide_end_request(drive, 1, done >> 9); } else xferfunc(drive, NULL, pc->cur_pos, bcount); @@ -481,7 +439,7 @@ cmd_finished: rq->cmd[0], bcount); next_irq: /* And set the interrupt handler again */ - ide_set_handler(drive, ide_pc_intr, timeout, expiry); + ide_set_handler(drive, ide_pc_intr, timeout, NULL); return ide_started; } -- cgit From 5317464dccd0c03026d60f1e9968de4f9cd23f69 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:54 +0100 Subject: ide: remove the last ide-scsi remnants Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 3 +-- drivers/ide/ide-io.c | 3 --- drivers/ide/ide-ioctls.c | 3 +-- drivers/ide/ide-probe.c | 2 -- 4 files changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 7a04509bf96..d412bd2bd7f 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -17,8 +17,7 @@ static inline int dev_is_idecd(ide_drive_t *drive) { - return (drive->media == ide_cdrom || drive->media == ide_optical) && - !(drive->dev_flags & IDE_DFLAG_SCSI); + return drive->media == ide_cdrom || drive->media == ide_optical; } /* diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index bb3248abf47..1c36a8e83d3 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -426,9 +426,6 @@ 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->cmd_type != REQ_TYPE_ATA_TASKFILE) { hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); } else { diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index 28232c64c34..1be263eb9c0 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -95,8 +95,7 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg) return -EPERM; if (((arg >> IDE_NICE_DSC_OVERLAP) & 1) && - (drive->media != ide_tape || - (drive->dev_flags & IDE_DFLAG_SCSI))) + (drive->media != ide_tape)) return -EPERM; if ((arg >> IDE_NICE_DSC_OVERLAP) & 1) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 966b74c1577..c5adb7b9c5b 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1141,8 +1141,6 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data) if (drive->media == ide_disk) request_module("ide-disk"); - if (drive->dev_flags & IDE_DFLAG_SCSI) - request_module("ide-scsi"); if (drive->media == ide_cdrom || drive->media == ide_optical) request_module("ide-cd"); if (drive->media == ide_tape) -- cgit From 8c662852d1aa35ed370942ef2740759cd334d2d5 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:54 +0100 Subject: ide-atapi: compute cmd_len based on device type in ide_transfer_pc There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov [bart: move cmd_len check closer to ->output_data() call] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index d412bd2bd7f..5fdcb953fc1 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -15,6 +15,8 @@ #define debug_log(fmt, args...) do {} while (0) #endif +#define ATAPI_MIN_CDB_BYTES 12 + static inline int dev_is_idecd(ide_drive_t *drive) { return drive->media == ide_cdrom || drive->media == ide_optical; @@ -492,6 +494,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) struct request *rq = hwif->hwgroup->rq; ide_expiry_t *expiry; unsigned int timeout; + int cmd_len; ide_startstop_t startstop; u8 ireason; @@ -513,9 +516,18 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " "a packet command\n", drive->name); + return ide_do_reset(drive); } + if (dev_is_idecd(drive)) { + /* ATAPI commands get padded out to 12 bytes minimum */ + cmd_len = COMMAND_SIZE(rq->cmd[0]); + if (cmd_len < ATAPI_MIN_CDB_BYTES) + cmd_len = ATAPI_MIN_CDB_BYTES; + } else + cmd_len = ATAPI_MIN_CDB_BYTES; + /* * If necessary schedule the packet transfer to occur 'timeout' * miliseconds later in ide_delayed_transfer_pc() after the device @@ -541,7 +553,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) /* Send the actual packet */ if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0) - hwif->tp_ops->output_data(drive, NULL, rq->cmd, 12); + hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); return ide_started; } -- cgit From def860d061d0fcab7fbbe193c0b8b8f0b9b4c828 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:55 +0100 Subject: ide-atapi: assign expiry and timeout based on device type There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 5fdcb953fc1..cf2b99c3736 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -525,21 +525,25 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) cmd_len = COMMAND_SIZE(rq->cmd[0]); if (cmd_len < ATAPI_MIN_CDB_BYTES) cmd_len = ATAPI_MIN_CDB_BYTES; - } else - cmd_len = ATAPI_MIN_CDB_BYTES; - /* - * If necessary schedule the packet transfer to occur 'timeout' - * miliseconds later in ide_delayed_transfer_pc() after the device - * says it's ready for a packet. - */ - if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { - timeout = drive->pc_delay; - expiry = &ide_delayed_transfer_pc; + timeout = rq->timeout; + expiry = ide_cd_expiry; } else { - timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD - : WAIT_TAPE_CMD; - expiry = NULL; + cmd_len = ATAPI_MIN_CDB_BYTES; + + /* + * If necessary schedule the packet transfer to occur 'timeout' + * miliseconds later in ide_delayed_transfer_pc() after the + * device says it's ready for a packet. + */ + if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) { + timeout = drive->pc_delay; + expiry = &ide_delayed_transfer_pc; + } else { + timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD + : WAIT_TAPE_CMD; + expiry = NULL; + } } /* Set the interrupt routine */ -- cgit From d77612ab0ad7515623b084b952dfefd547073ada Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:55 +0100 Subject: ide-atapi: split drive-specific functionality in ide_issue_pc There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index cf2b99c3736..fa7a70a3f24 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -564,39 +564,43 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout) { - struct ide_atapi_pc *pc = drive->pc; + struct ide_atapi_pc *pc; ide_hwif_t *hwif = drive->hwif; ide_expiry_t *expiry = NULL; u32 tf_flags; u16 bcount; - /* We haven't transferred any data yet */ - pc->xferred = 0; - pc->cur_pos = pc->buf; - if (dev_is_idecd(drive)) { tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; bcount = ide_cd_get_xferlen(hwif->hwgroup->rq); expiry = ide_cd_expiry; + + if (drive->dma) + drive->dma = !hwif->dma_ops->dma_setup(drive); } else { + pc = drive->pc; + + /* We haven't transferred any data yet */ + pc->xferred = 0; + pc->cur_pos = pc->buf; + tf_flags = IDE_TFLAG_OUT_DEVICE; bcount = ((drive->media == ide_tape) ? pc->req_xfer : min(pc->req_xfer, 63 * 1024)); - } - if (pc->flags & PC_FLAG_DMA_ERROR) { - pc->flags &= ~PC_FLAG_DMA_ERROR; - ide_dma_off(drive); - } + if (pc->flags & PC_FLAG_DMA_ERROR) { + pc->flags &= ~PC_FLAG_DMA_ERROR; + ide_dma_off(drive); + } - if (((pc->flags & PC_FLAG_DMA_OK) && - (drive->dev_flags & IDE_DFLAG_USING_DMA)) || - drive->dma) - drive->dma = !hwif->dma_ops->dma_setup(drive); + if ((pc->flags & PC_FLAG_DMA_OK) && + (drive->dev_flags & IDE_DFLAG_USING_DMA)) + drive->dma = !hwif->dma_ops->dma_setup(drive); - if (!drive->dma) - pc->flags &= ~PC_FLAG_DMA_OK; + if (!drive->dma) + pc->flags &= ~PC_FLAG_DMA_OK; + } ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); -- cgit From 563d993153ab16d829ba373c5c070a118eb1eba4 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:55 +0100 Subject: ide-cd: remove xferlen arg to cdrom_start_packet_command There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 105e4d855e6..34981f578e2 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -520,10 +520,13 @@ end_request: * will be called immediately after the drive is prepared for the transfer. */ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, - int xferlen, ide_handler_t *handler) { ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->hwgroup->rq; + int xferlen; + + xferlen = ide_cd_get_xferlen(rq); ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen); @@ -1175,15 +1178,12 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { ide_handler_t *fn; - int xferlen; ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " "rq->cmd_type: 0x%x, block: %llu\n", __func__, rq->cmd[0], rq->cmd_type, (unsigned long long)block); - xferlen = ide_cd_get_xferlen(rq); - if (blk_fs_request(rq)) { fn = cdrom_start_rw_cont; @@ -1210,7 +1210,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, return ide_stopped; } - return cdrom_start_packet_command(drive, xferlen, fn); + return cdrom_start_packet_command(drive, fn); } /* -- cgit From 65a3309e552585c4908e50e3c9736afb764c97c0 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:55 +0100 Subject: ide-cd: remove handler wrappers Remove cdrom_do_newpc_cont and cdrom_start_rw_cont wrappers and pass cdrom_transfer_packet_command to ide_execute_command directly. There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov [bart: don't move cdrom_start_packet_command() around, remove newlines] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 49 +++++++++++-------------------------------------- 1 file changed, 11 insertions(+), 38 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 34981f578e2..1a7410f8824 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -511,6 +511,9 @@ end_request: return 1; } +static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *); +static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); + /* * Set up the device registers for transferring a packet command on DEV, * expecting to later transfer XFERLEN bytes. HANDLER is the routine @@ -519,8 +522,7 @@ end_request: * called when the interrupt from the drive arrives. Otherwise, HANDLER * will be called immediately after the drive is prepared for the transfer. */ -static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, - ide_handler_t *handler) +static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->hwgroup->rq; @@ -544,13 +546,14 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, drive->waiting_for_dma = 0; /* packet command */ - ide_execute_command(drive, ATA_CMD_PACKET, handler, + ide_execute_command(drive, ATA_CMD_PACKET, + cdrom_transfer_packet_command, ATAPI_WAIT_PC, ide_cd_expiry); return ide_started; } else { ide_execute_pkt_cmd(drive); - return (*handler) (drive); + return cdrom_transfer_packet_command(drive); } } @@ -561,11 +564,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, * there's data ready. */ #define ATAPI_MIN_CDB_BYTES 12 -static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, - struct request *rq, - ide_handler_t *handler) +static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; + struct request *rq = hwif->hwgroup->rq; int cmd_len; ide_startstop_t startstop; @@ -592,7 +594,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, } /* arm the interrupt handler */ - ide_set_handler(drive, handler, rq->timeout, ide_cd_expiry); + ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, ide_cd_expiry); /* ATAPI commands get padded out to 12 bytes minimum */ cmd_len = COMMAND_SIZE(rq->cmd[0]); @@ -680,8 +682,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) return 1; } -static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); - static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, struct request *rq) { @@ -723,20 +723,6 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, return ide_started; } -/* - * Routine to send a read/write packet command to the drive. This is usually - * called directly from cdrom_start_{read,write}(). However, for drq_interrupt - * devices, it is called from an interrupt when the drive is ready to accept - * the command. - */ -static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive) -{ - struct request *rq = drive->hwif->hwgroup->rq; - - /* send the command to the drive and return */ - return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); -} - /* * Fix up a possibly partially-processed request so that we can start it over * entirely, or even put it back on the request queue. @@ -1126,13 +1112,6 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) return ide_started; } -static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) -{ - struct request *rq = HWGROUP(drive)->rq; - - return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); -} - static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { @@ -1177,16 +1156,12 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { - ide_handler_t *fn; - ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " "rq->cmd_type: 0x%x, block: %llu\n", __func__, rq->cmd[0], rq->cmd_type, (unsigned long long)block); if (blk_fs_request(rq)) { - fn = cdrom_start_rw_cont; - if (cdrom_start_rw(drive, rq) == ide_stopped) return ide_stopped; @@ -1194,8 +1169,6 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, return ide_stopped; } else if (blk_sense_request(rq) || blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { - fn = cdrom_do_newpc_cont; - if (!rq->timeout) rq->timeout = ATAPI_WAIT_PC; @@ -1210,7 +1183,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, return ide_stopped; } - return cdrom_start_packet_command(drive, fn); + return cdrom_start_packet_command(drive); } /* -- cgit From 28ad91db77755f1c49d79652de11b28ee2cfbf03 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:56 +0100 Subject: ide-atapi: remove timeout arg to ide_issue_pc There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 7 ++++++- drivers/ide/ide-floppy.c | 2 +- drivers/ide/ide-tape.c | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index fa7a70a3f24..c470dbb155c 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -562,11 +562,12 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) return ide_started; } -ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout) +ide_startstop_t ide_issue_pc(ide_drive_t *drive) { struct ide_atapi_pc *pc; ide_hwif_t *hwif = drive->hwif; ide_expiry_t *expiry = NULL; + unsigned int timeout; u32 tf_flags; u16 bcount; @@ -574,6 +575,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout) tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; bcount = ide_cd_get_xferlen(hwif->hwgroup->rq); expiry = ide_cd_expiry; + timeout = ATAPI_WAIT_PC; if (drive->dma) drive->dma = !hwif->dma_ops->dma_setup(drive); @@ -600,6 +602,9 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, unsigned int timeout) if (!drive->dma) pc->flags &= ~PC_FLAG_DMA_OK; + + timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD + : WAIT_TAPE_CMD; } ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma); diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index fdec729d0e4..0a48e2dc53a 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -197,7 +197,7 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, pc->retries++; - return ide_issue_pc(drive, WAIT_FLOPPY_CMD); + return ide_issue_pc(drive); } void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index ac9e29a4991..5d2aa22cd6e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -694,7 +694,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, pc->retries++; - return ide_issue_pc(drive, WAIT_TAPE_CMD); + return ide_issue_pc(drive); } /* A mode sense command is used to "sense" tape parameters. */ -- cgit From 06cc2778a1744b79edcfa394ce2d41f09134b2b1 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:56 +0100 Subject: ide-atapi: put the rest of non-ide-cd code into the else-clause of ide_transfer_pc There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index c470dbb155c..c9beda5fca1 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -509,17 +509,6 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) drive->waiting_for_dma = 1; } - ireason = ide_read_ireason(drive); - if (drive->media == ide_tape) - ireason = ide_wait_ireason(drive, ireason); - - if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { - printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " - "a packet command\n", drive->name); - - return ide_do_reset(drive); - } - if (dev_is_idecd(drive)) { /* ATAPI commands get padded out to 12 bytes minimum */ cmd_len = COMMAND_SIZE(rq->cmd[0]); @@ -544,6 +533,17 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) : WAIT_TAPE_CMD; expiry = NULL; } + + ireason = ide_read_ireason(drive); + if (drive->media == ide_tape) + ireason = ide_wait_ireason(drive, ireason); + + if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { + printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " + "a packet command\n", drive->name); + + return ide_do_reset(drive); + } } /* Set the interrupt routine */ -- cgit From b16aabc9374217fa2d28e72fd9a6e6d60905e1b9 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 2 Jan 2009 16:12:56 +0100 Subject: ide-atapi: start dma in a drive-specific way There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-atapi.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/ide') diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index c9beda5fca1..e8688c0f864 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -489,7 +489,7 @@ static int ide_delayed_transfer_pc(ide_drive_t *drive) static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) { - struct ide_atapi_pc *pc = drive->pc; + struct ide_atapi_pc *uninitialized_var(pc); ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->hwgroup->rq; ide_expiry_t *expiry; @@ -518,6 +518,8 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) timeout = rq->timeout; expiry = ide_cd_expiry; } else { + pc = drive->pc; + cmd_len = ATAPI_MIN_CDB_BYTES; /* @@ -550,9 +552,14 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) ide_set_handler(drive, ide_pc_intr, timeout, expiry); /* Begin DMA, if necessary */ - if (pc->flags & PC_FLAG_DMA_OK) { - pc->flags |= PC_FLAG_DMA_IN_PROGRESS; - hwif->dma_ops->dma_start(drive); + if (dev_is_idecd(drive)) { + if (drive->dma) + hwif->dma_ops->dma_start(drive); + } else { + if (pc->flags & PC_FLAG_DMA_OK) { + pc->flags |= PC_FLAG_DMA_IN_PROGRESS; + hwif->dma_ops->dma_start(drive); + } } /* Send the actual packet */ -- cgit