summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Dalecki <dalecki@evision-ventures.com>2002-07-14 03:20:46 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-07-14 03:20:46 -0700
commit2dbd15029c00ec56983a240a98306e8ea4101baa (patch)
treef355166242752dc1f5f770fcb88fe72fbbc2bd67
parent5b2a157778e975a6f66720deca07a3aeed07cafc (diff)
[PATCH] IDE 98
Synchronize with 2.5.25. Incorporate IDE-94, as well as 95, 96, 97 and 98-pre as announced by Bartek and unfortunately still not included in 2.5.25, which makes admittedly things still fall appart: Missing changelog for 98-pre by Bartlomiej Zolnierkiewicz (BTW. Handling Unicode should be essential at least to make proper crediting of many many peoples possible!) follows here: - add missing channel->lock unlocking/locking and fix some comments in ide_timer_expiry() - allow PCI drivers to disable autodma in ->init_dma() (bug introduced in IDE 97, affects sl82c105.c only) noticed by Russell King - alim15x3.c, if revision is <= 0x20 disable autodma - remove unneeded checks (drive.dn > 3) from pdc202xx.c and sis5513.c - use block layer wrappers And my additions follow: - Fix TCQ code. Patch based on work by Alexander Atanasov. - Use the FreeBSD derived request handler return values: ATA_OP_FINISHED ATA_OP_CONTINUES ATA_OP_RELEASED ATA_OP_READY /* for status ready reporting during poll */ - PMAC compilation fix by Paul Mackerras. - Simplify the ata_status_poll function significantly. - Fix logic used to prevent drive IRQ assertion from drive on channels sharing our interrupt. NOTE: We will move it later to the time where a request is really finished soon. - Don't use ata_busy_poll() use ata_status_poll() instead. This increases code unification. NOTE: We should maybe invent some way to prevent the error recovery path to be taken at all. In esp to prevent ata_error from trying to reissue commands.
-rw-r--r--arch/cris/drivers/ide.c4
-rw-r--r--drivers/block/ll_rw_blk.c30
-rw-r--r--drivers/ide/aec62xx.c33
-rw-r--r--drivers/ide/alim15x3.c155
-rw-r--r--drivers/ide/amd74xx.c36
-rw-r--r--drivers/ide/ata-timing.c8
-rw-r--r--drivers/ide/ata-timing.h25
-rw-r--r--drivers/ide/cmd64x.c120
-rw-r--r--drivers/ide/cs5530.c17
-rw-r--r--drivers/ide/cy82c693.c5
-rw-r--r--drivers/ide/device.c66
-rw-r--r--drivers/ide/hpt34x.c105
-rw-r--r--drivers/ide/hpt366.c151
-rw-r--r--drivers/ide/icside.c10
-rw-r--r--drivers/ide/ide-cd.c178
-rw-r--r--drivers/ide/ide-disk.c612
-rw-r--r--drivers/ide/ide-floppy.c434
-rw-r--r--drivers/ide/ide-pci.c22
-rw-r--r--drivers/ide/ide-pmac.c26
-rw-r--r--drivers/ide/ide-tape.c360
-rw-r--r--drivers/ide/ide-taskfile.c48
-rw-r--r--drivers/ide/ide.c369
-rw-r--r--drivers/ide/ioctl.c32
-rw-r--r--drivers/ide/it8172.c16
-rw-r--r--drivers/ide/main.c5
-rw-r--r--drivers/ide/ns87415.c8
-rw-r--r--drivers/ide/pcidma.c107
-rw-r--r--drivers/ide/pcihost.h1
-rw-r--r--drivers/ide/pdc202xx.c194
-rw-r--r--drivers/ide/pdc4030.c114
-rw-r--r--drivers/ide/piix.c52
-rw-r--r--drivers/ide/probe.c30
-rw-r--r--drivers/ide/serverworks.c93
-rw-r--r--drivers/ide/sis5513.c118
-rw-r--r--drivers/ide/sl82c105.c3
-rw-r--r--drivers/ide/tcq.c75
-rw-r--r--drivers/ide/trm290.c11
-rw-r--r--drivers/ide/via82cxxx.c38
-rw-r--r--drivers/scsi/ide-scsi.c94
-rw-r--r--include/linux/atapi.h281
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/ide.h70
42 files changed, 1508 insertions, 2650 deletions
diff --git a/arch/cris/drivers/ide.c b/arch/cris/drivers/ide.c
index 330734bc6bd3..89ae840968e8 100644
--- a/arch/cris/drivers/ide.c
+++ b/arch/cris/drivers/ide.c
@@ -703,11 +703,11 @@ static ide_startstop_t etrax_dma_intr(struct ata_device *drive, struct request *
i -= rq->current_nr_sectors;
ide_end_request(drive, rq, 1);
}
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
printk("%s: bad DMA status\n", drive->name);
}
- return ata_error(drive, __FUNCTION__);
+ return ata_error(drive, rq, __FUNCTION__);
}
/*
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 3dda5dc8eefb..48616f94f5ee 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -1202,6 +1202,26 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
return rq;
}
+/*
+ * Non-locking blk_get_request variant, for special requests from drivers.
+ */
+struct request *__blk_get_request(request_queue_t *q, int rw)
+{
+ struct request *rq;
+
+ BUG_ON(rw != READ && rw != WRITE);
+
+ rq = get_request(q, rw);
+
+ if (rq) {
+ rq->flags = 0;
+ rq->buffer = NULL;
+ rq->bio = rq->biotail = NULL;
+ rq->waiting = NULL;
+ }
+ return rq;
+}
+
void blk_put_request(struct request *rq)
{
blkdev_release_request(rq);
@@ -1381,6 +1401,14 @@ void blk_attempt_remerge(request_queue_t *q, struct request *rq)
spin_unlock_irqrestore(q->queue_lock, flags);
}
+/*
+ * Non-locking blk_attempt_remerge variant.
+ */
+void __blk_attempt_remerge(request_queue_t *q, struct request *rq)
+{
+ attempt_back_merge(q, rq);
+}
+
static int __make_request(request_queue_t *q, struct bio *bio)
{
struct request *req, *freereq = NULL;
@@ -2039,6 +2067,7 @@ EXPORT_SYMBOL(generic_unplug_device);
EXPORT_SYMBOL(blk_plug_device);
EXPORT_SYMBOL(blk_remove_plug);
EXPORT_SYMBOL(blk_attempt_remerge);
+EXPORT_SYMBOL(__blk_attempt_remerge);
EXPORT_SYMBOL(blk_max_low_pfn);
EXPORT_SYMBOL(blk_max_pfn);
EXPORT_SYMBOL(blk_queue_max_sectors);
@@ -2055,6 +2084,7 @@ EXPORT_SYMBOL(blk_queue_assign_lock);
EXPORT_SYMBOL(blk_phys_contig_segment);
EXPORT_SYMBOL(blk_hw_contig_segment);
EXPORT_SYMBOL(blk_get_request);
+EXPORT_SYMBOL(__blk_get_request);
EXPORT_SYMBOL(blk_put_request);
EXPORT_SYMBOL(blk_queue_prep_rq);
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
index fa3c5d6111cc..855139e39ac3 100644
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -160,16 +160,15 @@ static void aec62xx_tune_drive(struct ata_device *drive, unsigned char pio)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-static int aec62xx_udma_setup(struct ata_device *drive)
+static int __init aec62xx_modes_map(struct ata_channel *ch)
{
- u32 bmide = pci_resource_start(drive->channel->pci_dev, 4);
- short speed;
+ u32 bmide = pci_resource_start(ch->pci_dev, 4);
int map;
- map = XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA | XFER_SWDMA | XFER_UDMA;
+ map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA;
- if (drive->channel->udma_four)
- switch (drive->channel->pci_dev->device) {
+ if (ch->udma_four)
+ switch (ch->pci_dev->device) {
case PCI_DEVICE_ID_ARTOP_ATP865R:
case PCI_DEVICE_ID_ARTOP_ATP865:
/* Can't use these modes simultaneously,
@@ -180,11 +179,7 @@ static int aec62xx_udma_setup(struct ata_device *drive)
map |= XFER_UDMA_66;
}
- speed = ata_timing_mode(drive, map);
- aec_set_drive(drive, speed);
- udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0);
-
- return 0;
+ return map;
}
#endif
@@ -256,11 +251,12 @@ static void __init aec62xx_init_channel(struct ata_channel *ch)
ch->tuneproc = aec62xx_tune_drive;
ch->speedproc = aec_set_drive;
- ch->autodma = 0;
ch->io_32bit = 1;
ch->unmask = 1;
+ ch->udma_four = aec62xx_ata66_check(ch);
+
for (i = 0; i < 2; i++) {
ch->drives[i].autotune = 1;
ch->drives[i].dn = ch->unit * 2 + i;
@@ -269,11 +265,8 @@ static void __init aec62xx_init_channel(struct ata_channel *ch)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (ch->dma_base) {
ch->highmem = 1;
- ch->udma_setup = aec62xx_udma_setup;
-#ifdef CONFIG_IDEDMA_AUTO
- if (!noautodma)
- ch->autodma = 1;
-#endif
+ ch->modes_map = aec62xx_modes_map(ch);
+ ch->udma_setup = udma_generic_setup;
}
#endif
}
@@ -306,17 +299,15 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_ARTOP,
device: PCI_DEVICE_ID_ARTOP_ATP860,
init_chipset: aec62xx_init_chipset,
- ata66_check: aec62xx_ata66_check,
init_channel: aec62xx_init_channel,
enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} },
bootable: NEVER_BOARD,
- flags: ATA_F_IRQ | ATA_F_NOADMA | ATA_F_DMA
+ flags: ATA_F_IRQ | ATA_F_DMA
},
{
vendor: PCI_VENDOR_ID_ARTOP,
device: PCI_DEVICE_ID_ARTOP_ATP860R,
init_chipset: aec62xx_init_chipset,
- ata66_check: aec62xx_ata66_check,
init_channel: aec62xx_init_channel,
enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} },
bootable: OFF_BOARD,
@@ -326,7 +317,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_ARTOP,
device: PCI_DEVICE_ID_ARTOP_ATP865,
init_chipset: aec62xx_init_chipset,
- ata66_check: aec62xx_ata66_check,
init_channel: aec62xx_init_channel,
enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} },
bootable: NEVER_BOARD,
@@ -336,7 +326,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_ARTOP,
device: PCI_DEVICE_ID_ARTOP_ATP865R,
init_chipset: aec62xx_init_chipset,
- ata66_check: aec62xx_ata66_check,
init_channel: aec62xx_init_channel,
enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} },
bootable: OFF_BOARD,
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index c23653140e31..63ccfd52a64d 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -99,43 +99,6 @@ static void ali15x3_tune_drive(struct ata_device *drive, byte pio)
__restore_flags(flags);
}
-static byte ali15x3_can_ultra(struct ata_device *drive)
-{
- if (m5229_revision <= 0x20) {
- return 0;
- } else if ((m5229_revision < 0xC2) &&
-#ifndef CONFIG_WDC_ALI15X3
- ((chip_is_1543c_e && strstr(drive->id->model, "WDC ")) ||
- (drive->type != ATA_DISK))) {
-#else
- (drive->type != ATA_DISK)) {
-#endif
- return 0;
- } else {
- return 1;
- }
-}
-
-static int ali15x3_ratemask(struct ata_device *drive)
-{
- int map = 0;
-
- if (!ali15x3_can_ultra(drive))
- return 0;
-
- map |= XFER_UDMA;
-
- if (!eighty_ninty_three(drive))
- return map;
-
- if (m5229_revision >= 0xC4)
- map |= XFER_UDMA_100;
- if (m5229_revision >= 0xC2)
- map |= XFER_UDMA_66;
-
- return map;
-}
-
static int ali15x3_tune_chipset(struct ata_device *drive, byte speed)
{
struct pci_dev *dev = drive->channel->pci_dev;
@@ -156,6 +119,7 @@ static int ali15x3_tune_chipset(struct ata_device *drive, byte speed)
if (speed < XFER_SW_DMA_0)
ali15x3_tune_drive(drive, speed);
#ifdef CONFIG_BLK_DEV_IDEDMA
+ /* FIXME: no support for MWDMA and SWDMA modes --bkz */
else if (speed >= XFER_UDMA_0) {
pci_read_config_byte(dev, m5229_udma, &tmpbyte);
tmpbyte &= (0x0f << ((1-unit) << 2));
@@ -176,91 +140,40 @@ static int ali15x3_tune_chipset(struct ata_device *drive, byte speed)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
+static int ali15x3_udma_setup(struct ata_device *drive, int map)
{
- int map;
- u8 mode;
-
- if (udma)
- map = ali15x3_ratemask(drive);
- else
- map = XFER_SWDMA | XFER_MWDMA;
-
- mode = ata_timing_mode(drive, map);
- if (mode < XFER_SW_DMA_0)
- return 0;
-
- return !ali15x3_tune_chipset(drive, mode);
+#ifndef CONFIG_WDC_ALI15X3
+ if ((m5229_revision < 0xC2) && chip_is_1543c_e &&
+ strstr(drive->id->model, "WDC "))
+ map &= ~XFER_UDMA_ALL;
+#endif
+ return udma_generic_setup(drive, map);
}
-static int ali15x3_udma_setup(struct ata_device *drive)
+static int ali15x3_udma_init(struct ata_device *drive, struct request *rq)
{
- struct hd_driveid *id = drive->id;
- struct ata_channel *hwif = drive->channel;
- int on = 1;
- int verbose = 1;
- byte can_ultra_dma = ali15x3_can_ultra(drive);
+ if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
+ return ATA_OP_FINISHED; /* try PIO instead of DMA */
- if ((m5229_revision<=0x20) && (drive->type != ATA_DISK)) {
- udma_enable(drive, 0, 0);
- return 0;
- }
+ return udma_pci_init(drive, rq);
+}
- if ((id != NULL) && ((id->capability & 1) != 0) && hwif->autodma) {
- /* Consult the list of known "bad" drives */
- if (udma_black_list(drive)) {
- on = 0;
- goto fast_ata_pio;
- }
- on = 0;
- verbose = 0;
- if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) {
- if (id->dma_ultra & 0x003F) {
- /* Force if Capable UltraDMA */
- on = config_chipset_for_dma(drive, can_ultra_dma);
- if ((id->field_valid & 2) &&
- (!on))
- goto try_dma_modes;
- }
- } else if (id->field_valid & 2) {
-try_dma_modes:
- if ((id->dma_mword & 0x0007) ||
- (id->dma_1word & 0x0007)) {
- /* Force if Capable regular DMA modes */
- on = config_chipset_for_dma(drive, can_ultra_dma);
- if (!on)
- goto no_dma_set;
- }
- } else if (udma_white_list(drive)) {
- if (id->eide_dma_time > 150) {
- goto no_dma_set;
- }
- /* Consult the list of known "good" drives */
- on = config_chipset_for_dma(drive, can_ultra_dma);
- if (!on)
- goto no_dma_set;
- } else {
- goto fast_ata_pio;
- }
- } else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
- on = 0;
- verbose = 0;
-no_dma_set:
- ali15x3_tune_drive(drive, 255);
- }
+static int __init ali15x3_modes_map(struct ata_channel *ch)
+{
+ int map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA;
- udma_enable(drive, on, verbose);
+ if (m5229_revision <= 0x20)
+ return map;
- return 0;
-}
+ map |= XFER_UDMA;
-static int ali15x3_udma_init(struct ata_device *drive, struct request *rq)
-{
- if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
- return ide_stopped; /* try PIO instead of DMA */
+ if (m5229_revision >= 0xC2) {
+ map |= XFER_UDMA_66;
+ if (m5229_revision >= 0xC4)
+ map |= XFER_UDMA_100;
+ }
- return udma_pci_init(drive, rq);
+ return map;
}
#endif
@@ -426,6 +339,8 @@ static void __init ali15x3_init_channel(struct ata_channel *hwif)
}
#endif /* CONFIG_SPARC64 */
+ hwif->udma_four = ali15x3_ata66_check(hwif);
+
hwif->tuneproc = &ali15x3_tune_drive;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
@@ -436,22 +351,21 @@ static void __init ali15x3_init_channel(struct ata_channel *hwif)
/*
* M1543C or newer for DMAing
*/
- hwif->udma_init = ali15x3_udma_init;
+ hwif->modes_map = ali15x3_modes_map(hwif);
+ if (m5229_revision < 0xC2)
+ hwif->no_atapi_autodma = 1;
hwif->udma_setup = ali15x3_udma_setup;
- hwif->autodma = 1;
+ hwif->udma_init = ali15x3_udma_init;
}
-
- if (noautodma)
- hwif->autodma = 0;
-#else
- hwif->autodma = 0;
#endif
}
static void __init ali15x3_init_dma(struct ata_channel *ch, unsigned long dmabase)
{
- if ((dmabase) && (m5229_revision < 0x20))
+ if (dmabase && (m5229_revision < 0x20)) {
+ ch->autodma = 0;
return;
+ }
ata_init_dma(ch, dmabase);
}
@@ -472,7 +386,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AL,
device: PCI_DEVICE_ID_AL_M5229,
init_chipset: ali15x3_init_chipset,
- ata66_check: ali15x3_ata66_check,
init_channel: ali15x3_init_channel,
init_dma: ali15x3_init_dma,
enablebits: { {0x00,0x00,0x00}, {0x00,0x00,0x00} },
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
index f3fb5c2fde30..49a2bb3fb9dd 100644
--- a/drivers/ide/amd74xx.c
+++ b/drivers/ide/amd74xx.c
@@ -175,21 +175,15 @@ static void amd74xx_tune_drive(struct ata_device *drive, u8 pio)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-static int amd74xx_udma_setup(struct ata_device *drive)
+static int __init amd_modes_map(struct ata_channel *ch)
{
- short w80 = drive->channel->udma_four;
+ short w80 = ch->udma_four;
+ int map = XFER_EPIO | XFER_MWDMA | XFER_UDMA |
+ ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
+ (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
+ (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0);
- short speed = ata_timing_mode(drive,
- XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA |
- ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
- (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
- (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0));
-
- amd_set_drive(drive, speed);
-
- udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0);
-
- return 0;
+ return map;
}
#endif
@@ -274,9 +268,10 @@ static void __init amd74xx_init_channel(struct ata_channel *hwif)
{
int i;
+ hwif->udma_four = amd74xx_ata66_check(hwif);
+
hwif->tuneproc = &amd74xx_tune_drive;
hwif->speedproc = &amd_set_drive;
- hwif->autodma = 0;
hwif->io_32bit = 1;
hwif->unmask = 1;
@@ -289,11 +284,8 @@ static void __init amd74xx_init_channel(struct ata_channel *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->highmem = 1;
- hwif->udma_setup = amd74xx_udma_setup;
-# ifdef CONFIG_IDEDMA_AUTO
- if (!noautodma)
- hwif->autodma = 1;
-# endif
+ hwif->modes_map = amd_modes_map(hwif);
+ hwif->udma_setup = udma_generic_setup;
}
#endif
}
@@ -314,7 +306,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_COBRA_7401,
init_chipset: amd74xx_init_chipset,
- ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
@@ -324,7 +315,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_VIPER_7409,
init_chipset: amd74xx_init_chipset,
- ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
@@ -335,7 +325,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_VIPER_7411,
init_chipset: amd74xx_init_chipset,
- ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
@@ -345,7 +334,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_OPUS_7441,
init_chipset: amd74xx_init_chipset,
- ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
@@ -355,7 +343,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_8111_IDE,
init_chipset: amd74xx_init_chipset,
- ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
@@ -365,7 +352,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_NVIDIA,
device: PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,
init_chipset: amd74xx_init_chipset,
- ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma,
enablebits: {{0x50,0x01,0x01}, {0x50,0x02,0x02}},
diff --git a/drivers/ide/ata-timing.c b/drivers/ide/ata-timing.c
index 84d82e600529..01a312044242 100644
--- a/drivers/ide/ata-timing.c
+++ b/drivers/ide/ata-timing.c
@@ -86,9 +86,11 @@ short ata_timing_mode(struct ata_device *drive, int map)
if ((map & XFER_UDMA_100) == XFER_UDMA_100)
if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best;
- if ((map & XFER_UDMA_66) == XFER_UDMA_66)
- if ((best = (id->dma_ultra & 0x0010) ? XFER_UDMA_4 :
- (id->dma_ultra & 0x0008) ? XFER_UDMA_3 : 0)) return best;
+ if ((map & XFER_UDMA_66_4) == XFER_UDMA_66_4)
+ if ((best = (id->dma_ultra & 0x0010) ? XFER_UDMA_4 : 0)) return best;
+
+ if ((map & XFER_UDMA_66_3) == XFER_UDMA_66_3)
+ if ((best = (id->dma_ultra & 0x0008) ? XFER_UDMA_3 : 0)) return best;
if ((best = (id->dma_ultra & 0x0004) ? XFER_UDMA_2 :
(id->dma_ultra & 0x0002) ? XFER_UDMA_1 :
diff --git a/drivers/ide/ata-timing.h b/drivers/ide/ata-timing.h
index 2f7543c0bae8..9f01f07e8329 100644
--- a/drivers/ide/ata-timing.h
+++ b/drivers/ide/ata-timing.h
@@ -59,15 +59,22 @@ extern struct ata_timing ata_timing[];
#define ENOUGH(v,unit) (((v)-1)/(unit)+1)
#define EZ(v,unit) ((v)?ENOUGH(v,unit):0)
-#define XFER_MODE 0xf0
-#define XFER_UDMA_133 0x48
-#define XFER_UDMA_100 0x44
-#define XFER_UDMA_66 0x42
-#define XFER_UDMA 0x40
-#define XFER_MWDMA 0x20
-#define XFER_SWDMA 0x10
-#define XFER_EPIO 0x01
-#define XFER_PIO 0x00
+/* see hpt366.c for details */
+#define XFER_UDMA_66_3 0x100
+#define XFER_UDMA_66_4 0x200
+
+#define XFER_MODE 0xff0
+#define XFER_UDMA_133 0x800
+#define XFER_UDMA_100 0x400
+#define XFER_UDMA_66 0x300
+#define XFER_UDMA 0x040
+#define XFER_MWDMA 0x020
+#define XFER_SWDMA 0x010
+#define XFER_EPIO 0x001
+#define XFER_PIO 0x000
+
+#define XFER_UDMA_ALL 0xf40
+#define XFER_UDMA_80W 0xf00
/* External interface to host chips channel timing setup.
*
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index cd71bbe3747b..c6adb2014380 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -217,10 +217,10 @@ static void cmd64x_tuneproc(struct ata_device *drive, u8 pio)
ide_config_drive_speed(drive, speed);
}
-static int cmd64x_ratemask(struct ata_device *drive)
+static int __init cmd6xx_modes_map(struct ata_channel *ch)
{
- struct pci_dev *dev = drive->channel->pci_dev;
- int map = 0;
+ struct pci_dev *dev = ch->pci_dev;
+ int map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA;
switch(dev->device) {
case PCI_DEVICE_ID_CMD_680:
@@ -234,10 +234,9 @@ static int cmd64x_ratemask(struct ata_device *drive)
break;
case PCI_DEVICE_ID_CMD_646:
{
- u32 class_rev;
- pci_read_config_dword(dev,
- PCI_CLASS_REVISION, &class_rev);
- class_rev &= 0xff;
+ u32 rev;
+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &rev);
+ rev &= 0xff;
/*
* UltraDMA only supported on PCI646U and PCI646U2, which
* correspond to revisions 0x03, 0x05 and 0x07 respectively.
@@ -250,7 +249,7 @@ static int cmd64x_ratemask(struct ata_device *drive)
*
* So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
*/
- switch(class_rev) {
+ switch(rev) {
case 0x07:
case 0x05:
map |= XFER_UDMA;
@@ -260,11 +259,6 @@ static int cmd64x_ratemask(struct ata_device *drive)
}
}
- if (!eighty_ninty_three(drive)) {
- if (map & XFER_UDMA)
- return XFER_UDMA;
- return 0;
- }
return map;
}
@@ -515,80 +509,6 @@ speed_break :
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
-{
- int map;
- u8 mode;
-
- if (udma)
- map = cmd64x_ratemask(drive);
- else
- map = XFER_SWDMA | XFER_MWDMA;
-
- mode = ata_timing_mode(drive, map);
-
- return !drive->channel->speedproc(drive, mode);
-}
-
-static int cmd6xx_udma_setup(struct ata_device *drive)
-{
- struct hd_driveid *id = drive->id;
- struct ata_channel *hwif = drive->channel;
- int on = 1;
- int verbose = 1;
-
- hwif->tuneproc(drive, 255);
-
- if ((id != NULL) && ((id->capability & 1) != 0) &&
- hwif->autodma && (drive->type == ATA_DISK)) {
- /* Consult the list of known "bad" drives */
- if (udma_black_list(drive)) {
- on = 0;
- goto fast_ata_pio;
- }
- on = 0;
- verbose = 0;
- if ((id->field_valid & 4)) {
- if (id->dma_ultra & 0x007F) {
- /* Force if Capable UltraDMA */
- on = config_chipset_for_dma(drive, 1);
- if ((id->field_valid & 2) &&
- (!on))
- goto try_dma_modes;
- }
- } else if (id->field_valid & 2) {
-try_dma_modes:
- if ((id->dma_mword & 0x0007) ||
- (id->dma_1word & 0x0007)) {
- /* Force if Capable regular DMA modes */
- on = config_chipset_for_dma(drive, 0);
- if (!on)
- goto no_dma_set;
- }
- } else if (udma_white_list(drive)) {
- if (id->eide_dma_time > 150) {
- goto no_dma_set;
- }
- /* Consult the list of known "good" drives */
- on = config_chipset_for_dma(drive, 0);
- if (!on)
- goto no_dma_set;
- } else {
- goto fast_ata_pio;
- }
- } else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
- on = 0;
- verbose = 0;
-no_dma_set:
- hwif->tuneproc(drive, 255);
- }
-
- udma_enable(drive, on, verbose);
-
- return 0;
-}
-
static int cmd64x_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
@@ -822,13 +742,6 @@ static unsigned int cmd64x_ata66(struct ata_channel *hwif)
return (ata66 & mask) ? 1 : 0;
}
-static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif)
-{
- if (hwif->pci_dev->device == PCI_DEVICE_ID_CMD_680)
- return cmd680_ata66(hwif);
- return cmd64x_ata66(hwif);
-}
-
static void __init cmd64x_init_channel(struct ata_channel *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
@@ -843,32 +756,28 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
switch(dev->device) {
case PCI_DEVICE_ID_CMD_680:
hwif->busproc = cmd680_busproc;
-#ifdef CONFIG_BLK_DEV_IDEDMA
- if (hwif->dma_base)
- hwif->udma_setup = cmd6xx_udma_setup;
-#endif
hwif->resetproc = cmd680_reset;
hwif->speedproc = cmd680_tune_chipset;
hwif->tuneproc = cmd680_tuneproc;
+ hwif->udma_four = cmd680_ata66(hwif);
break;
case PCI_DEVICE_ID_CMD_649:
case PCI_DEVICE_ID_CMD_648:
case PCI_DEVICE_ID_CMD_643:
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
- hwif->udma_setup = cmd6xx_udma_setup;
hwif->udma_stop = cmd64x_udma_stop;
hwif->udma_irq_status = cmd64x_udma_irq_status;
}
#endif
hwif->tuneproc = cmd64x_tuneproc;
hwif->speedproc = cmd64x_tune_chipset;
+ hwif->udma_four = cmd64x_ata66(hwif);
break;
case PCI_DEVICE_ID_CMD_646:
hwif->chipset = ide_cmd646;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
- hwif->udma_setup = cmd6xx_udma_setup;
if (class_rev == 0x01) {
hwif->udma_stop = cmd646_1_udma_stop;
} else {
@@ -879,6 +788,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
#endif
hwif->tuneproc = cmd64x_tuneproc;
hwif->speedproc = cmd64x_tune_chipset;
+ hwif->udma_four = cmd64x_ata66(hwif);
break;
default:
break;
@@ -887,10 +797,9 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->highmem = 1;
-# ifdef CONFIG_IDEDMA_AUTO
- if (!noautodma)
- hwif->autodma = 1;
-# endif
+ hwif->modes_map = cmd6xx_modes_map(hwif);
+ hwif->no_atapi_autodma = 1;
+ hwif->udma_setup = udma_generic_setup;
}
#endif
}
@@ -919,7 +828,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_CMD,
device: PCI_DEVICE_ID_CMD_648,
init_chipset: cmd64x_init_chipset,
- ata66_check: cmd64x_ata66_check,
init_channel: cmd64x_init_channel,
bootable: ON_BOARD,
flags: ATA_F_DMA
@@ -928,7 +836,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_CMD,
device: PCI_DEVICE_ID_CMD_649,
init_chipset: cmd64x_init_chipset,
- ata66_check: cmd64x_ata66_check,
init_channel: cmd64x_init_channel,
bootable: ON_BOARD,
flags: ATA_F_DMA
@@ -937,7 +844,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_CMD,
device: PCI_DEVICE_ID_CMD_680,
init_chipset: cmd64x_init_chipset,
- ata66_check: cmd64x_ata66_check,
init_channel: cmd64x_init_channel,
bootable: ON_BOARD,
flags: ATA_F_DMA
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index 770282983261..13913e0e1cad 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -191,7 +191,7 @@ static int cs5530_config_dma(struct ata_device *drive)
return 0;
}
-static int cs5530_udma_setup(struct ata_device *drive)
+static int cs5530_udma_setup(struct ata_device *drive, int map)
{
return cs5530_config_dma(drive);
}
@@ -285,17 +285,15 @@ static unsigned int __init pci_init_cs5530(struct pci_dev *dev)
*/
static void __init ide_init_cs5530(struct ata_channel *hwif)
{
+ u32 basereg, d0_timings;
+
hwif->serialized = 1;
- if (!hwif->dma_base) {
- hwif->autodma = 0;
- } else {
- unsigned int basereg, d0_timings;
#ifdef CONFIG_BLK_DEV_IDEDMA
- hwif->udma_setup = cs5530_udma_setup;
- hwif->highmem = 1;
-#else
- hwif->autodma = 0;
+ if (hwif->dma_base) {
+ hwif->highmem = 1;
+ hwif->udma_setup = cs5530_udma_setup;
+ }
#endif
hwif->tuneproc = &cs5530_tuneproc;
@@ -311,7 +309,6 @@ static void __init ide_init_cs5530(struct ata_channel *hwif)
if (!hwif->drives[1].autotune)
hwif->drives[1].autotune = 1; /* needs autotuning later */
}
- }
}
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
index 9916686225a0..9c22b523392e 100644
--- a/drivers/ide/cy82c693.c
+++ b/drivers/ide/cy82c693.c
@@ -237,7 +237,7 @@ static void cy82c693_dma_enable(struct ata_device *drive, int mode, int single)
/*
* used to set DMA mode for CY82C693 (single and multi modes)
*/
-static int cy82c693_udma_setup(struct ata_device *drive)
+static int cy82c693_udma_setup(struct ata_device *drive, int map)
{
/*
* Set dma mode for drive everything else is done by the defaul func.
@@ -414,14 +414,11 @@ static void __init ide_init_cy82c693(struct ata_channel *hwif)
hwif->tuneproc = cy82c693_tune_drive;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
- hwif->autodma = 0;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->highmem = 1;
hwif->udma_setup = cy82c693_udma_setup;
- if (!noautodma)
- hwif->autodma = 1;
}
#endif
}
diff --git a/drivers/ide/device.c b/drivers/ide/device.c
index e6ee8cf217eb..cd457931a8e2 100644
--- a/drivers/ide/device.c
+++ b/drivers/ide/device.c
@@ -80,29 +80,7 @@ void ata_mask(struct ata_device *drive)
}
/*
- * Spin until the drive is no longer busy.
- *
- * Not exported, since it's not used within any modules.
- */
-int ata_busy_poll(struct ata_device *drive, unsigned long timeout)
-{
- /* spec allows drive 400ns to assert "BUSY" */
- udelay(1);
- if (!ata_status(drive, 0, BUSY_STAT)) {
- timeout += jiffies;
- while (!ata_status(drive, 0, BUSY_STAT)) {
- if (time_after(jiffies, timeout))
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
* Check the state of the status register.
- *
- * FIXME: Channel lock should be held.
*/
int ata_status(struct ata_device *drive, u8 good, u8 bad)
{
@@ -120,31 +98,33 @@ EXPORT_SYMBOL(ata_status);
* all of the "good" bits and none of the "bad" bits, and if all is okay it
* returns 0. All other cases return 1 after invoking error handler -- caller
* should just return.
- *
- * This routine should get fixed to not hog the cpu during extra long waits..
- * That could be done by busy-waiting for the first jiffy or two, and then
- * setting a timer to wake up at half second intervals thereafter, until
- * timeout is achieved, before timing out.
- *
- * Channel lock should be held.
*/
int ata_status_poll(struct ata_device *drive, u8 good, u8 bad,
- unsigned long timeout,
- struct request *rq, ide_startstop_t *startstop)
+ unsigned long timeout, struct request *rq)
{
int i;
/* bail early if we've exceeded max_failures */
- if (drive->max_failures && (drive->failures > drive->max_failures)) {
- *startstop = ide_stopped;
-
- return 1;
- }
-
- if (ata_busy_poll(drive, timeout)) {
- *startstop = ata_error(drive, rq, "status timeout");
+ if (drive->max_failures && (drive->failures > drive->max_failures))
+ return ATA_OP_FINISHED;
+ /*
+ * Spin until the drive is no longer busy.
+ * Spec allows drive 400ns to assert "BUSY"
+ */
+ udelay(1);
+ if (!ata_status(drive, 0, BUSY_STAT)) {
+ unsigned long flags;
- return 1;
+ __save_flags(flags);
+ ide__sti();
+ timeout += jiffies;
+ while (!ata_status(drive, 0, BUSY_STAT)) {
+ if (time_after(jiffies, timeout)) {
+ __restore_flags(flags);
+ return ata_error(drive, rq, "status timeout");
+ }
+ }
+ __restore_flags(flags);
}
/*
@@ -156,12 +136,10 @@ int ata_status_poll(struct ata_device *drive, u8 good, u8 bad,
for (i = 0; i < 10; i++) {
udelay(1);
if (ata_status(drive, good, bad))
- return 0;
+ return ATA_OP_READY;
}
- *startstop = ata_error(drive, rq, "status error");
-
- return 1;
+ return ata_error(drive, rq, "status error");
}
EXPORT_SYMBOL(ata_status_poll);
diff --git a/drivers/ide/hpt34x.c b/drivers/ide/hpt34x.c
index 308e48fb70da..e7dad9da10a7 100644
--- a/drivers/ide/hpt34x.c
+++ b/drivers/ide/hpt34x.c
@@ -72,83 +72,13 @@ static void hpt34x_tune_drive(struct ata_device *drive, u8 pio)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
+static int hpt34x_udma_setup(struct ata_device *drive, int map)
{
- int map;
- u8 mode;
-
- if (drive->type != ATA_DISK)
- return 0;
-
- if (udma)
- map = XFER_UDMA;
- else
- map = XFER_SWDMA | XFER_MWDMA;
-
- mode = ata_timing_mode(drive, map);
- if (mode < XFER_SW_DMA_0)
- return 0;
-
- return !hpt34x_tune_chipset(drive, mode);
-}
-
-static int hpt34x_udma_setup(struct ata_device *drive)
-{
- struct hd_driveid *id = drive->id;
- int on = 1;
- int verbose = 1;
-
- if (id && (id->capability & 1) && drive->channel->autodma) {
- /* Consult the list of known "bad" drives */
- if (udma_black_list(drive)) {
- on = 0;
- goto fast_ata_pio;
- }
- on = 0;
- verbose = 0;
- if (id->field_valid & 4) {
- if (id->dma_ultra & 0x0007) {
- /* Force if Capable UltraDMA */
- on = config_chipset_for_dma(drive, 1);
- if ((id->field_valid & 2) &&
- (!on))
- goto try_dma_modes;
- }
- } else if (id->field_valid & 2) {
-try_dma_modes:
- if ((id->dma_mword & 0x0007) ||
- (id->dma_1word & 0x0007)) {
- /* Force if Capable regular DMA modes */
- on = config_chipset_for_dma(drive, 0);
- if (!on)
- goto no_dma_set;
- }
- } else if (udma_white_list(drive)) {
- if (id->eide_dma_time > 150) {
- goto no_dma_set;
- }
- /* Consult the list of known "good" drives */
- on = config_chipset_for_dma(drive, 0);
- if (!on)
- goto no_dma_set;
- } else {
- goto fast_ata_pio;
- }
- } else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
- on = 0;
- verbose = 0;
-no_dma_set:
- hpt34x_tune_chipset(drive, ata_best_pio_mode(drive));
- }
-
-#ifndef CONFIG_HPT34X_AUTODMA
- if (on)
- on = 0;
-#endif
- udma_enable(drive, on, verbose);
-
+#ifdef CONFIG_HPT34X_AUTODMA
+ return udma_generic_setup(drive, map);
+#else
return 0;
+#endif
}
static int hpt34x_udma_stop(struct ata_device *drive)
@@ -173,7 +103,7 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq)
u8 cmd;
if (!(count = udma_new_table(drive, rq)))
- return ide_stopped; /* try PIO instead of DMA */
+ return ATA_OP_FINISHED; /* try PIO instead of DMA */
if (rq_data_dir(rq) == READ)
cmd = 0x09;
@@ -189,7 +119,7 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq)
OUT_BYTE((cmd == 0x09) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
}
- return ide_started;
+ return ATA_OP_CONTINUES;
}
#endif
@@ -252,24 +182,21 @@ static void __init ide_init_hpt34x(struct ata_channel *hwif)
unsigned short pcicmd = 0;
pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd);
- if (!noautodma)
- hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
- else
- hwif->autodma = 0;
-
+#ifdef CONFIG_IDEDMA_AUTO
+ hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
+#endif
hwif->udma_stop = hpt34x_udma_stop;
hwif->udma_init = hpt34x_udma_init;
+ hwif->modes_map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA;
+ hwif->no_atapi_autodma = 1;
hwif->udma_setup = hpt34x_udma_setup;
hwif->highmem = 1;
- } else {
+ } else
+#endif
+ {
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
}
-#else
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
- hwif->autodma = 0;
-#endif
}
@@ -281,7 +208,7 @@ static struct ata_pci_device chipset __initdata = {
init_channel: ide_init_hpt34x,
bootable: NEVER_BOARD,
extra: 16,
- flags: ATA_F_NOADMA | ATA_F_DMA
+ flags: ATA_F_DMA
};
int __init init_hpt34x(void)
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 9d9b076c4591..0afee25c1289 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -493,37 +493,23 @@ static unsigned int hpt_revision(struct pci_dev *dev)
return class_rev;
}
-static int hpt3xx_ratemask(struct ata_device *drive)
+static int __init hpt3xx_modes_map(struct ata_channel *ch)
{
- u32 rev = hpt_revision(drive->channel->pci_dev);
- int map = XFER_UDMA;
+ u32 rev = hpt_revision(ch->pci_dev);
+ int map = XFER_EPIO | XFER_MWDMA | XFER_UDMA | XFER_UDMA_66;
if (rev >= 8) { /* HPT374 */
if (HPT374_ALLOW_ATA133_6)
map |= XFER_UDMA_133;
- map |= (XFER_UDMA_100 | XFER_UDMA_66);
+ map |= XFER_UDMA_100;
} else if (rev >= 5) { /* HPT372 */
if (HPT372_ALLOW_ATA133_6)
map |= XFER_UDMA_133;
- map |= (XFER_UDMA_100 | XFER_UDMA_66);
- } else if (rev >= 4) { /* HPT370A */
+ map |= XFER_UDMA_100;
+ } else if (rev >= 3) { /* HPT370A / HPT370 */
if (HPT370_ALLOW_ATA100_5)
map |= XFER_UDMA_100;
- map |= XFER_UDMA_66;
- } else if (rev >= 3) { /* HPT370 */
- if (HPT370_ALLOW_ATA100_5)
- map |= XFER_UDMA_100;
- map |= XFER_UDMA_66;
- if (check_in_drive_lists(drive, bad_ata33))
- return 0;
- } else { /* HPT366 and HPT368 */
- map |= XFER_UDMA_66;
- if (check_in_drive_lists(drive, bad_ata33))
- return 0;
- }
-
- if (!eighty_ninty_three(drive))
- return XFER_UDMA;
+ } /* HPT366 / HPT368 */
return map;
}
@@ -662,62 +648,42 @@ static int hpt3xx_tune_chipset(struct ata_device *drive, u8 speed)
return ide_config_drive_speed(drive, speed);
}
+/* FIXME: pio == 255 -> ata_best_pio_mode(drive) --bkz */
static void hpt3xx_tune_drive(struct ata_device *drive, u8 pio)
{
(void) hpt3xx_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4));
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_chipset_for_dma(struct ata_device *drive)
+static int hpt3xx_udma_setup(struct ata_device *drive, int map)
{
- int map;
u32 rev;
- u8 mode;
if (drive->type != ATA_DISK)
return 0;
rev = hpt_revision(drive->channel->pci_dev);
- /* FIXME: check SWDMA modes --bkz */
- map = hpt3xx_ratemask(drive) | XFER_MWDMA;
- mode = ata_timing_mode(drive, map);
+ /* FIXME: badlists need futher investigation --bkz */
- /* FIXME: badlists need futher investigation --bkz
- bad_ata100_5 is for HPT370/370A,
- bad_ata66_4, bad_ata66_3 and bad_ata33 are for HPT366/368
- */
- if (mode == XFER_UDMA_5 && rev < 5) {
- if (check_in_drive_lists(drive, bad_ata100_5)) {
- /* FIXME: make XFER_UDMA_66/100/133
- independent of XFER_UDMA --bkz */
- map &= ~XFER_UDMA_100;
- map |= XFER_UDMA;
- mode = ata_timing_mode(drive, map);
- }
- }
- if (mode == XFER_UDMA_4 && rev < 3) {
- if (check_in_drive_lists(drive, bad_ata66_4)) {
- if (drive->id->dma_ultra & 0x0008) {
- mode = XFER_UDMA_3;
- } else {
- map &= ~XFER_UDMA_66;
- map |= XFER_UDMA;
- mode = ata_timing_mode(drive, map);
- }
- }
- }
- if (mode == XFER_UDMA_3 && rev < 3) {
- if (check_in_drive_lists(drive, bad_ata66_3)) {
- map &= ~XFER_UDMA_66;
- map |= XFER_UDMA;
- mode = ata_timing_mode(drive, map);
- }
+ /* bad_ata100_5 is for HPT370/370A,
+ bad_ata66_4, bad_ata66_3 and bad_ata33 are for HPT366/368 */
+
+ if (rev < 5 && check_in_drive_lists(drive, bad_ata100_5))
+ map &= ~XFER_UDMA_100;
+
+ if (rev < 3) {
+ if (check_in_drive_lists(drive, bad_ata66_4))
+ map &= ~XFER_UDMA_66_4;
+
+ if (check_in_drive_lists(drive, bad_ata66_3))
+ map &= ~XFER_UDMA_66_3;
+
+ if (check_in_drive_lists(drive, bad_ata33))
+ map &= ~XFER_UDMA_ALL;
}
- if (check_in_drive_lists(drive, bad_ata33) && rev < 3)
- mode = ata_timing_mode(drive, XFER_MWDMA);
- return !hpt3xx_tune_chipset(drive, mode);
+ return udma_generic_setup(drive, map);
}
static int hpt3xx_quirkproc(struct ata_device *drive)
@@ -754,59 +720,6 @@ static void hpt3xx_maskproc(struct ata_device *drive)
}
}
-static int hpt3xx_udma_setup(struct ata_device *drive)
-{
- struct hd_driveid *id = drive->id;
- int on = 1;
- int verbose = 1;
-
- if (id && (id->capability & 1) && drive->channel->autodma) {
- /* Consult the list of known "bad" drives */
- if (udma_black_list(drive)) {
- on = 0;
- goto fast_ata_pio;
- }
- on = 0;
- verbose = 0;
- if (id->field_valid & 4) {
- if (id->dma_ultra & 0x007F) {
- /* Force if Capable UltraDMA */
- on = config_chipset_for_dma(drive);
- if ((id->field_valid & 2) &&
- (!on))
- goto try_dma_modes;
- }
- } else if (id->field_valid & 2) {
-try_dma_modes:
- if (id->dma_mword & 0x0007) {
- /* Force if Capable regular DMA modes */
- on = config_chipset_for_dma(drive);
- if (!on)
- goto no_dma_set;
- }
- } else if (udma_white_list(drive)) {
- if (id->eide_dma_time > 150) {
- goto no_dma_set;
- }
- /* Consult the list of known "good" drives */
- on = config_chipset_for_dma(drive);
- if (!on)
- goto no_dma_set;
- } else {
- goto fast_ata_pio;
- }
- } else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
- on = 0;
- verbose = 0;
-no_dma_set:
- hpt3xx_tune_chipset(drive, ata_best_pio_mode(drive));
- }
- udma_enable(drive, on, verbose);
-
- return 0;
-}
-
static void hpt366_udma_irq_lost(struct ata_device *drive)
{
struct pci_dev *dev = drive->channel->pci_dev;
@@ -1232,6 +1145,8 @@ static void __init hpt366_init_channel(struct ata_channel *ch)
struct pci_dev *dev = ch->pci_dev;
u32 rev = hpt_revision(dev);
+ ch->udma_four = hpt366_ata66_check(ch);
+
ch->tuneproc = hpt3xx_tune_drive;
ch->speedproc = hpt3xx_tune_chipset;
ch->quirkproc = hpt3xx_quirkproc;
@@ -1272,17 +1187,12 @@ static void __init hpt366_init_channel(struct ata_channel *ch)
// ch->resetproc = hpt3xx_reset;
// ch->busproc = hpt3xx_tristate;
}
+ ch->modes_map = hpt3xx_modes_map(ch);
ch->udma_setup = hpt3xx_udma_setup;
-
- if (!noautodma)
- ch->autodma = 1;
- else
- ch->autodma = 0;
ch->highmem = 1;
} else
#endif
{
- ch->autodma = 0;
ch->drives[0].autotune = 1;
ch->drives[1].autotune = 1;
}
@@ -1315,7 +1225,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_TTI,
device: PCI_DEVICE_ID_TTI_HPT366,
init_chipset: hpt366_init_chipset,
- ata66_check: hpt366_ata66_check,
init_channel: hpt366_init_channel,
init_dma: hpt366_init_dma,
bootable: OFF_BOARD,
@@ -1326,7 +1235,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_TTI,
device: PCI_DEVICE_ID_TTI_HPT372,
init_chipset: hpt366_init_chipset,
- ata66_check: hpt366_ata66_check,
init_channel: hpt366_init_channel,
init_dma: hpt366_init_dma,
bootable: OFF_BOARD,
@@ -1337,7 +1245,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_TTI,
device: PCI_DEVICE_ID_TTI_HPT374,
init_chipset: hpt366_init_chipset,
- ata66_check: hpt366_ata66_check,
init_channel: hpt366_init_channel,
init_dma: hpt366_init_dma,
bootable: OFF_BOARD,
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 3ba18c93f2fb..cd2af4ca8faa 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -405,7 +405,7 @@ static void icside_dma_enable(struct ata_device *drive, int on, int verbose)
#endif
}
-static int icside_dma_check(struct ata_device *drive)
+static int icside_dma_check(struct ata_device *drive, int map)
{
struct hd_driveid *id = drive->id;
struct ata_channel *ch = drive->channel;
@@ -466,7 +466,7 @@ static ide_startstop_t icside_dmaintr(struct ata_device *drive, struct request *
if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
if (!dma_stat) {
__ide_end_request(drive, rq, 1, rq->nr_sectors);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat);
@@ -516,10 +516,10 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq)
u8 int cmd;
if (icside_dma_common(drive, rq, DMA_MODE_WRITE))
- return ide_stopped;
+ return ATA_OP_FINISHED;
if (drive->type != ATA_DISK)
- return ide_started;
+ return ATA_OP_CONTINUES;
ata_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL);
@@ -535,7 +535,7 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq)
enable_dma(ch->hw.dma);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
static int icside_irq_status(struct ata_device *drive)
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 0e0388efd705..4e9b658002c2 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -556,7 +556,7 @@ static void cdrom_end_request(struct ata_device *drive, struct request *rq, int
if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
uptodate = 1;
- ata_end_request(drive, rq, uptodate);
+ __ata_end_request(drive, rq, uptodate, 0);
}
@@ -581,7 +581,7 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr
if (rq == NULL) {
printk("%s: missing rq in %s\n", drive->name, __FUNCTION__);
- *startstop = ide_stopped;
+ *startstop = ATA_OP_FINISHED;
return 1;
}
@@ -688,14 +688,12 @@ static int cdrom_decode_status(ide_startstop_t *startstop, struct ata_device *dr
blk_dump_rq_flags(rq, "ide-cd bad flags");
/* Retry, or handle the next request. */
- *startstop = ide_stopped;
+ *startstop = ATA_OP_FINISHED;
return 1;
}
-static int cdrom_timer_expiry(struct ata_device *drive, struct request *rq)
+static ide_startstop_t cdrom_timer_expiry(struct ata_device *drive, struct request *rq, unsigned long *wait)
{
- unsigned long wait = 0;
-
/*
* Some commands are *slow* and normally take a long time to
* complete. Usually we can use the ATAPI "disconnect" to bypass
@@ -706,14 +704,14 @@ static int cdrom_timer_expiry(struct ata_device *drive, struct request *rq)
case GPCMD_BLANK:
case GPCMD_FORMAT_UNIT:
case GPCMD_RESERVE_RZONE_TRACK:
- wait = WAIT_CMD;
- break;
+ *wait = WAIT_CMD;
+ return ATA_OP_CONTINUES;
default:
- wait = 0;
+ *wait = 0;
break;
}
- return wait;
+ return ATA_OP_FINISHED;
}
/* Set up the device registers for transferring a packet command on DEV,
@@ -728,51 +726,40 @@ static ide_startstop_t cdrom_start_packet_command(struct ata_device *drive,
int xferlen,
ata_handler_t handler)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
- ide_startstop_t startstop;
struct cdrom_info *info = drive->driver_data;
int ret;
- spin_lock_irqsave(ch->lock, flags);
/* Wait for the controller to be idle. */
- if (ata_status_poll(drive, 0, BUSY_STAT, WAIT_READY, rq, &startstop))
- ret = startstop;
- else {
- if (info->dma) {
- if (info->cmd == READ || info->cmd == WRITE)
- info->dma = udma_init(drive, rq);
- else
- printk("ide-cd: DMA set, but not allowed\n");
- }
+ ret = ata_status_poll(drive, 0, BUSY_STAT, WAIT_READY, rq);
+ if (ret != ATA_OP_READY)
+ return ret;
- /* Set up the controller registers. */
- OUT_BYTE(info->dma, IDE_FEATURE_REG);
- OUT_BYTE(0, IDE_NSECTOR_REG);
- OUT_BYTE(0, IDE_SECTOR_REG);
-
- OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG);
- OUT_BYTE(xferlen >> 8 , IDE_HCYL_REG);
- ata_irq_enable(drive, 1);
- if (info->dma)
- udma_start(drive, rq);
-
- if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
- ata_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
- OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
- ret = ide_started;
- } else {
- OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
+ if (info->dma) {
+ if (info->cmd == READ || info->cmd == WRITE)
+ info->dma = udma_init(drive, rq);
+ else
+ printk("ide-cd: DMA set, but not allowed\n");
+ }
- /* FIXME: Oj kurwa! We have to ungrab the lock before
- * the IRQ handler gets called.
- */
- spin_unlock_irqrestore(ch->lock, flags);
- ret = handler(drive, rq);
- spin_lock_irqsave(ch->lock, flags);
- }
+ /* Set up the controller registers. */
+ OUT_BYTE(info->dma, IDE_FEATURE_REG);
+ OUT_BYTE(0, IDE_NSECTOR_REG);
+ OUT_BYTE(0, IDE_SECTOR_REG);
+
+ OUT_BYTE(xferlen & 0xff, IDE_LCYL_REG);
+ OUT_BYTE(xferlen >> 8 , IDE_HCYL_REG);
+ ata_irq_enable(drive, 1);
+ if (info->dma)
+ udma_start(drive, rq);
+
+ if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
+ ata_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
+ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
+ ret = ATA_OP_CONTINUES;
+ } else {
+ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
+ ret = handler(drive, rq);
}
- spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
@@ -787,8 +774,6 @@ static ide_startstop_t cdrom_transfer_packet_command(struct ata_device *drive,
unsigned char *cmd, unsigned long timeout,
ata_handler_t handler)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
ide_startstop_t startstop;
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
@@ -800,26 +785,18 @@ static ide_startstop_t cdrom_transfer_packet_command(struct ata_device *drive,
if (cdrom_decode_status(&startstop, drive, rq, DRQ_STAT, &stat_dum))
return startstop;
} else {
- /* FIXME: make this locking go away */
- spin_lock_irqsave(ch->lock, flags);
/* Otherwise, we must wait for DRQ to get set. */
- if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
- WAIT_READY, rq, &startstop)) {
- spin_unlock_irqrestore(ch->lock, flags);
-
+ startstop = ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
+ WAIT_READY, rq);
+ if (startstop != ATA_OP_READY)
return startstop;
- }
- spin_unlock_irqrestore(ch->lock, flags);
}
/* Arm the interrupt handler and send the command to the device. */
- /* FIXME: make this locking go away */
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, handler, timeout, cdrom_timer_expiry);
atapi_write(drive, cmd, CDROM_PACKET_SIZE);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
/****************************************************************************
@@ -917,8 +894,6 @@ int cdrom_read_check_ireason(struct ata_device *drive, struct request *rq, int l
*/
static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
int stat;
int ireason, len, sectors_to_transfer, nskip;
struct cdrom_info *info = drive->driver_data;
@@ -937,15 +912,9 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
if (dma) {
if (!dma_error) {
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
__ata_end_request(drive, rq, 1, rq->nr_sectors);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_stopped;
+ return ATA_OP_FINISHED;
} else
return ata_error(drive, rq, "dma error");
}
@@ -964,12 +933,12 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
cdrom_end_request(drive, rq, 0);
} else
cdrom_end_request(drive, rq, 1);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/* Check that the drive is expecting to do the same thing we are. */
if (cdrom_read_check_ireason(drive, rq, len, ireason))
- return ide_stopped;
+ return ATA_OP_FINISHED;
/* Assume that the drive will always provide data in multiples
of at least SECTOR_SIZE, as it gets hairy to keep track
@@ -984,7 +953,7 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
}
cdrom_end_request(drive, rq, 0);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/* The number of sectors we need to read from the drive. */
@@ -1040,11 +1009,9 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
}
/* Done moving data! Wait for another interrupt. */
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, cdrom_read_intr, WAIT_CMD, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
/*
@@ -1132,7 +1099,7 @@ static ide_startstop_t cdrom_start_read_continuation(struct ata_device *drive, s
printk ("%s: %s: buffer botch (%u)\n",
drive->name, __FUNCTION__, rq->current_nr_sectors);
cdrom_end_request(drive, rq, 0);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
sector -= nskip;
nsect += nskip;
@@ -1181,7 +1148,7 @@ static ide_startstop_t cdrom_seek_intr(struct ata_device *drive, struct request
drive->dsc_overlap = 0;
}
}
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
static ide_startstop_t cdrom_start_seek_continuation(struct ata_device *drive, struct request *rq)
@@ -1243,7 +1210,7 @@ static ide_startstop_t cdrom_start_read(struct ata_device *drive, struct request
/* Satisfy whatever we can of this request from our cached sector. */
if (cdrom_read_from_buffer(drive, rq))
- return ide_stopped;
+ return ATA_OP_FINISHED;
blk_attempt_remerge(&drive->queue, rq);
@@ -1269,8 +1236,6 @@ static ide_startstop_t cdrom_start_read(struct ata_device *drive, struct request
/* Interrupt routine for packet command completion. */
static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
int ireason, len, stat, thislen;
/* FIXME --mdcki */
@@ -1312,7 +1277,7 @@ static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *r
pc->stat = 1;
cdrom_end_request(drive, rq, 1);
}
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/* Figure out how much data to transfer. */
@@ -1363,11 +1328,9 @@ static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *r
}
/* Now we wait for another interrupt. */
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
static ide_startstop_t cdrom_do_pc_continuation(struct ata_device *drive, struct request *rq)
@@ -1508,8 +1471,6 @@ static inline int cdrom_write_check_ireason(struct ata_device *drive, struct req
static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
int stat, ireason, len, sectors_to_transfer, uptodate;
struct cdrom_info *info = drive->driver_data;
int dma_error = 0, dma = info->dma;
@@ -1536,15 +1497,9 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request
if (dma_error)
return ata_error(drive, rq, "dma error");
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
__ata_end_request(drive, rq, 1, rq->nr_sectors);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/* Read the interrupt reason and the transfer length. */
@@ -1563,13 +1518,13 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request
uptodate = 0;
}
cdrom_end_request(drive, rq, uptodate);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/* Check that the drive is expecting to do the same thing we are. */
if (ireason & 3)
if (cdrom_write_check_ireason(drive, rq, len, ireason))
- return ide_stopped;
+ return ATA_OP_FINISHED;
sectors_to_transfer = len / SECTOR_SIZE;
@@ -1607,11 +1562,9 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request
}
/* re-arm handler */
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, cdrom_write_intr, 5 * WAIT_CMD, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
static ide_startstop_t cdrom_start_write_cont(struct ata_device *drive, struct request *rq)
@@ -1628,7 +1581,7 @@ static ide_startstop_t cdrom_start_write(struct ata_device *drive, struct reques
*/
if ((rq->nr_sectors & 3) || (rq->sector & 3)) {
cdrom_end_request(drive, rq, 0);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/*
@@ -1658,7 +1611,6 @@ static ide_startstop_t cdrom_start_write(struct ata_device *drive, struct reques
static ide_startstop_t
ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
- struct ata_channel *ch = drive->channel;
int ret;
struct cdrom_info *info = drive->driver_data;
@@ -1669,14 +1621,12 @@ ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t bloc
if (!ata_status(drive, SEEK_STAT, 0)) {
if (elpased < IDECD_SEEK_TIMEOUT) {
ide_stall_queue(drive, IDECD_SEEK_TIMER);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
printk ("%s: DSC timeout\n", drive->name);
}
CDROM_CONFIG_FLAGS(drive)->seeking = 0;
}
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) {
ret = cdrom_start_seek(drive, rq, block);
} else {
@@ -1686,13 +1636,9 @@ ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t bloc
ret = cdrom_start_write(drive, rq);
}
info->last_block = block;
- spin_lock_irq(ch->lock);
return ret;
} else if (rq->flags & (REQ_PC | REQ_SENSE)) {
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
ret = cdrom_do_packet_command(drive, rq);
- spin_lock_irq(ch->lock);
return ret;
} else if (rq->flags & REQ_SPECIAL) {
@@ -1703,12 +1649,9 @@ ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t bloc
* right now this can only be a reset...
*/
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
cdrom_end_request(drive, rq, 1);
- spin_lock_irq(ch->lock);
- return ide_stopped;
+ return ATA_OP_FINISHED;
} else if (rq->flags & REQ_BLOCK_PC) {
struct packet_command pc;
ide_startstop_t startstop;
@@ -1720,10 +1663,7 @@ ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t bloc
/* FIXME --mdcki */
rq->special = (char *) &pc;
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
startstop = cdrom_do_packet_command(drive, rq);
- spin_lock_irq(ch->lock);
if (pc.stat)
++rq->errors;
@@ -1732,12 +1672,10 @@ ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t bloc
}
blk_dump_rq_flags(rq, "ide-cd bad flags");
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
+
cdrom_end_request(drive, rq, 0);
- spin_lock_irq(ch->lock);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 221fa7a1e304..cf9a29aa0e93 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -11,8 +11,6 @@
* This is the ATA disk device driver, as evolved from hd.c and ide.c.
*/
-#define IDEDISK_VERSION "1.14"
-
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -41,6 +39,24 @@
#endif
/*
+ * for now, taskfile requests are special :/
+ */
+static inline char *ide_map_rq(struct request *rq, unsigned long *flags)
+{
+ if (rq->bio)
+ return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
+ else
+ return rq->buffer + ((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE;
+}
+
+static inline void ide_unmap_rq(struct request *rq, char *to,
+ unsigned long *flags)
+{
+ if (rq->bio)
+ bio_kunmap_irq(to, flags);
+}
+
+/*
* Perform a sanity check on the claimed "lba_capacity"
* value for this drive (from its reported identification information).
*
@@ -95,25 +111,17 @@ static int lba_capacity_is_ok(struct hd_driveid *id)
*/
static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
int ret;
- spin_lock_irqsave(ch->lock, flags);
-
if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
- if (drive->status & (ERR_STAT | DRQ_STAT)) {
- spin_unlock_irqrestore(ch->lock, flags);
-
+ if (drive->status & (ERR_STAT | DRQ_STAT))
return ata_error(drive, rq, __FUNCTION__);
- }
/* no data yet, so wait for another interrupt */
ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
- ret = ide_started;
+ ret = ATA_OP_CONTINUES;
} else {
-
// printk("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
{
unsigned long flags;
@@ -134,18 +142,16 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq
if (rq->current_nr_sectors <= 0) {
if (!__ata_end_request(drive, rq, 1, 0)) {
// printk("Request Ended stat: %02x\n", drive->status);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
}
/* still data left to transfer */
ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
- ret = ide_started;
+ ret = ATA_OP_CONTINUES;
}
- spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
@@ -155,19 +161,13 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq
*/
static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
int ret;
- spin_lock_irqsave(ch->lock, flags);
- if (!ata_status(drive, DRIVE_READY, drive->bad_wstat)) {
- spin_unlock_irqrestore(ch->lock, flags);
-
+ if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
return ata_error(drive, rq, __FUNCTION__);
- }
if (!rq->current_nr_sectors && !__ata_end_request(drive, rq, 1, 0)) {
- ret = ide_stopped;
+ ret = ATA_OP_FINISHED;
} else {
if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
unsigned long flags;
@@ -183,9 +183,8 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r
}
ata_set_handler(drive, task_out_intr, WAIT_CMD, NULL);
- ret = ide_started;
+ ret = ATA_OP_CONTINUES;
}
- spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
@@ -195,22 +194,16 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r
*/
static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
int ret;
- spin_lock_irqsave(ch->lock, flags);
if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
- if (drive->status & (ERR_STAT | DRQ_STAT)) {
- spin_unlock_irqrestore(ch->lock, flags);
-
+ if (drive->status & (ERR_STAT | DRQ_STAT))
return ata_error(drive, rq, __FUNCTION__);
- }
/* no data yet, so wait for another interrupt */
ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
- ret = ide_started;
+ ret = ATA_OP_CONTINUES;
} else {
unsigned int msect;
@@ -242,11 +235,8 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request
/* FIXME: this seems buggy */
if (rq->current_nr_sectors <= 0) {
- if (!__ata_end_request(drive, rq, 1, 0)) {
- spin_unlock_irqrestore(ch->lock, flags);
-
- return ide_stopped;
- }
+ if (!__ata_end_request(drive, rq, 1, 0))
+ return ATA_OP_FINISHED;
}
msect -= nsect;
} while (msect);
@@ -254,22 +244,17 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request
/* more data left */
ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
- ret = ide_started;
+ ret = ATA_OP_CONTINUES;
}
- spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
int ok;
int ret;
- spin_lock_irqsave(ch->lock, flags);
-
/*
* FIXME: the drive->status checks here seem to be messy.
*
@@ -280,24 +265,24 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
ok = ata_status(drive, DATA_READY, BAD_R_STAT);
if (!ok || !rq->nr_sectors) {
- if (drive->status & (ERR_STAT | DRQ_STAT)) {
- spin_unlock_irqrestore(ch->lock, flags);
-
+ if (drive->status & (ERR_STAT | DRQ_STAT))
return ata_error(drive, rq, __FUNCTION__);
- }
}
if (!rq->nr_sectors) {
__ata_end_request(drive, rq, 1, rq->hard_nr_sectors);
rq->bio = NULL;
- ret = ide_stopped;
+ ret = ATA_OP_FINISHED;
} else if (!ok) {
- /* no data yet, so wait for another interrupt */
- if (!ch->handler)
- ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
- ret = ide_started;
+ /* not ready yet, so wait for next IRQ */
+ ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
+
+ ret = ATA_OP_CONTINUES;
} else {
int mcount = drive->mult_count;
+ /* prepare for next IRQ */
+ ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
+
do {
char *buf;
int nsect = rq->current_nr_sectors;
@@ -325,6 +310,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
}
}
+ rq->errors = 0; /* FIXME: why? --bzolnier */
/*
* Ok, we're all setup for the interrupt re-entering us on the
@@ -334,31 +320,209 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
bio_kunmap_irq(buf, &flags);
} while (mcount);
- rq->errors = 0;
-
- if (!ch->handler)
- ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
-
- ret = ide_started;
+ ret = ATA_OP_CONTINUES;
}
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ret;
}
/*
- * Channel lock should be held on entry.
+ * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
+ * otherwise, to address sectors. It also takes care of issuing special
+ * DRIVE_CMDs.
*/
-static ide_startstop_t __do_request(struct ata_device *drive,
- struct ata_taskfile *ar, struct request *rq)
+static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
+ struct ata_taskfile args;
+ struct ata_taskfile *ar;
struct hd_driveid *id = drive->id;
+ u8 cmd;
+
+ /* Special drive commands don't need any kind of setup.
+ */
+ if (rq->flags & REQ_SPECIAL) {
+ ar = rq->special;
+ cmd = ar->cmd;
+ } else {
+ unsigned int sectors;
+
+ /* FIXME: this check doesn't make sense */
+ if (!(rq->flags & REQ_CMD)) {
+ blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
+ __ata_end_request(drive, rq, 0, 0);
+
+ return ATA_OP_FINISHED;
+ }
+
+ if (IS_PDC4030_DRIVE) {
+ extern ide_startstop_t promise_do_request(struct ata_device *, struct request *, sector_t);
+
+ return promise_do_request(drive, rq, block);
+ }
+
+ /*
+ * start a tagged operation
+ */
+ if (drive->using_tcq) {
+ int st = blk_queue_start_tag(&drive->queue, rq);
+
+ if (ata_pending_commands(drive) > drive->max_depth)
+ drive->max_depth = ata_pending_commands(drive);
+ if (ata_pending_commands(drive) > drive->max_last_depth)
+ drive->max_last_depth = ata_pending_commands(drive);
+
+ if (st) {
+ BUG_ON(!ata_pending_commands(drive));
+
+ return ATA_OP_CONTINUES;
+ }
+ }
+ ar = &args;
+
+ memset(&args, 0, sizeof(args));
+ sectors = rq->nr_sectors;
+ /* Dispatch depending up on the drive access method. */
+ if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) {
+ /* LBA 48 bit */
+ /*
+ * 268435455 == 137439 MB or 28bit limit
+ * 320173056 == 163929 MB or 48bit addressing
+ * 1073741822 == 549756 MB or 48bit addressing fake drive
+ */
+ if (sectors == 65536)
+ sectors = 0;
+
+ if (blk_rq_tagged(rq)) {
+ args.taskfile.feature = sectors;
+ args.hobfile.feature = sectors >> 8;
+ args.taskfile.sector_count = rq->tag << 3;
+ } else {
+ args.taskfile.sector_count = sectors;
+ args.hobfile.sector_count = sectors >> 8;
+ }
+
+ args.taskfile.sector_number = block; /* low lba */
+ args.taskfile.low_cylinder = (block >>= 8); /* mid lba */
+ args.taskfile.high_cylinder = (block >>= 8); /* hi lba */
+ args.taskfile.device_head = drive->select.all;
+
+ args.hobfile.sector_number = (block >>= 8); /* low lba */
+ args.hobfile.low_cylinder = (block >>= 8); /* mid lba */
+ args.hobfile.high_cylinder = (block >>= 8); /* hi lba */
+ } else if (drive->select.b.lba) {
+ /* LBA 28 bit */
+ if (sectors == 256)
+ sectors = 0;
+
+ if (blk_rq_tagged(rq)) {
+ args.taskfile.feature = sectors;
+ args.taskfile.sector_count = rq->tag << 3;
+ } else
+ args.taskfile.sector_count = sectors;
+
+ args.taskfile.sector_number = block;
+ args.taskfile.low_cylinder = (block >>= 8);
+ args.taskfile.high_cylinder = (block >>= 8);
+ args.taskfile.device_head = ((block >> 8) & 0x0f);
+ } else {
+ /* CHS */
+ unsigned int track = (block / drive->sect);
+ unsigned int sect = (block % drive->sect) + 1;
+ unsigned int head = (track % drive->head);
+ unsigned int cyl = (track / drive->head);
+
+ if (sectors == 256)
+ sectors = 0;
+
+ if (blk_rq_tagged(rq)) {
+ args.taskfile.feature = sectors;
+ args.taskfile.sector_count = rq->tag << 3;
+ } else
+ args.taskfile.sector_count = sectors;
+
+ args.taskfile.sector_number = sect;
+ args.taskfile.low_cylinder = cyl;
+ args.taskfile.high_cylinder = (cyl>>8);
+ args.taskfile.device_head = head;
+ }
+ args.taskfile.device_head |= drive->select.all;
+
+ /*
+ * Decode with physical ATA command to use and setup associated data.
+ */
+
+ if (rq_data_dir(rq) == READ) {
+ args.command_type = IDE_DRIVE_TASK_IN;
+ if (drive->addressing) {
+ if (drive->using_tcq) {
+ cmd = WIN_READDMA_QUEUED_EXT;
+ } else if (drive->using_dma) {
+ cmd = WIN_READDMA_EXT;
+ } else if (drive->mult_count) {
+ args.XXX_handler = task_mulin_intr;
+ cmd = WIN_MULTREAD_EXT;
+ } else {
+ args.XXX_handler = task_in_intr;
+ cmd = WIN_READ_EXT;
+ }
+ } else {
+ if (drive->using_tcq) {
+ cmd = WIN_READDMA_QUEUED;
+ } else if (drive->using_dma) {
+ cmd = WIN_READDMA;
+ } else if (drive->mult_count) {
+ args.XXX_handler = task_mulin_intr;
+ cmd = WIN_MULTREAD;
+ } else {
+ args.XXX_handler = task_in_intr;
+ cmd = WIN_READ;
+ }
+ }
+ } else {
+ args.command_type = IDE_DRIVE_TASK_RAW_WRITE;
+ if (drive->addressing) {
+ if (drive->using_tcq) {
+ cmd = WIN_WRITEDMA_QUEUED_EXT;
+ } else if (drive->using_dma) {
+ cmd = WIN_WRITEDMA_EXT;
+ } else if (drive->mult_count) {
+ args.XXX_handler = task_mulout_intr;
+ cmd = WIN_MULTWRITE_EXT;
+ } else {
+ args.XXX_handler = task_out_intr;
+ cmd = WIN_WRITE_EXT;
+ }
+ } else {
+ if (drive->using_tcq) {
+ cmd = WIN_WRITEDMA_QUEUED;
+ } else if (drive->using_dma) {
+ cmd = WIN_WRITEDMA;
+ } else if (drive->mult_count) {
+ args.XXX_handler = task_mulout_intr;
+ cmd = WIN_MULTWRITE;
+ } else {
+ args.XXX_handler = task_out_intr;
+ cmd = WIN_WRITE;
+ }
+ }
+ }
+#ifdef DEBUG
+ printk("%s: %sing: ", drive->name,
+ (rq_data_dir(rq)==READ) ? "read" : "writ");
+ if (lba) printk("LBAsect=%lld, ", block);
+ else printk("CHS=%d/%d/%d, ", cyl, head, sect);
+ printk("sectors=%ld, ", rq->nr_sectors);
+ printk("buffer=%p\n", rq->buffer);
+#endif
+ ar->cmd = cmd;
+ rq->special = ar;
+ }
/* (ks/hs): Moved to start, do not use for multiple out commands.
* FIXME: why not?! */
- if (!(ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
- ar->cmd == WIN_MULTWRITE ||
- ar->cmd == WIN_MULTWRITE_EXT)) {
+ if (!(cmd == CFA_WRITE_MULTI_WO_ERASE ||
+ cmd == WIN_MULTWRITE ||
+ cmd == WIN_MULTWRITE_EXT)) {
ata_irq_enable(drive, 1);
ata_mask(drive);
}
@@ -372,57 +536,58 @@ static ide_startstop_t __do_request(struct ata_device *drive,
OUT_BYTE((ar->taskfile.device_head & (drive->addressing ? 0xE0 : 0xEF)) | drive->select.all,
IDE_SELECT_REG);
+ /* FIXME: this is actually distingushing between PIO and DMA requests.
+ */
if (ar->XXX_handler) {
- struct ata_channel *ch = drive->channel;
+ if (ar->command_type == IDE_DRIVE_TASK_IN ||
+ ar->command_type == IDE_DRIVE_TASK_NO_DATA) {
- ata_set_handler(drive, ar->XXX_handler, WAIT_CMD, NULL);
- OUT_BYTE(ar->cmd, IDE_COMMAND_REG);
+ ata_set_handler(drive, ar->XXX_handler, WAIT_CMD, NULL);
+ OUT_BYTE(cmd, IDE_COMMAND_REG);
+
+ return ATA_OP_CONTINUES;
+ }
/* FIXME: Warning check for race between handler and prehandler
* for writing first block of data. however since we are well
* inside the boundaries of the seek, we should be okay.
- *
- * FIXME: Replace the switch by using a proper command_type.
+ * FIXME: should be fixed --bzolnier
*/
+ if (ar->command_type == IDE_DRIVE_TASK_RAW_WRITE) {
+ ide_startstop_t ret;
+
+ OUT_BYTE(cmd, IDE_COMMAND_REG);
- if (ar->cmd == CFA_WRITE_SECT_WO_ERASE ||
- ar->cmd == WIN_WRITE ||
- ar->cmd == WIN_WRITE_EXT ||
- ar->cmd == WIN_WRITE_VERIFY ||
- ar->cmd == WIN_WRITE_BUFFER ||
- ar->cmd == WIN_DOWNLOAD_MICROCODE ||
- ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
- ar->cmd == WIN_MULTWRITE ||
- ar->cmd == WIN_MULTWRITE_EXT) {
- ide_startstop_t startstop;
-
- if (ata_status_poll(drive, DATA_READY, drive->bad_wstat,
- WAIT_DRQ, rq, &startstop)) {
+ ret = ata_status_poll(drive, DATA_READY, drive->bad_wstat,
+ WAIT_DRQ, rq);
+ if (ret != ATA_OP_READY) {
printk(KERN_ERR "%s: no DRQ after issuing %s\n",
drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
- return startstop;
+ return ret;
}
/* FIXME: This doesn't make the slightest sense.
* (ks/hs): Fixed Multi Write
*/
- if (!(ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
- ar->cmd == WIN_MULTWRITE ||
- ar->cmd == WIN_MULTWRITE_EXT)) {
+ if (!(cmd == CFA_WRITE_MULTI_WO_ERASE ||
+ cmd == WIN_MULTWRITE ||
+ cmd == WIN_MULTWRITE_EXT)) {
unsigned long flags;
char *buf = ide_map_rq(rq, &flags);
+ ata_set_handler(drive, ar->XXX_handler, WAIT_CMD, NULL);
+
/* For Write_sectors we need to stuff the first sector */
+ /* FIXME: what if !rq->current_nr_sectors --bzolnier */
ata_write(drive, buf, SECTOR_WORDS);
rq->current_nr_sectors--;
ide_unmap_rq(rq, buf, &flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
} else {
int i;
- int ret;
/* Polling wait until the drive is ready.
*
@@ -438,14 +603,16 @@ static ide_startstop_t __do_request(struct ata_device *drive,
break;
}
if (!drive_is_ready(drive)) {
- printk(KERN_ERR "DISASTER WAITING TO HAPPEN!\n");
+ /* We are compleatly missing an error
+ * return path here.
+ * FIXME: We have only one? -alat
+ */
+ printk(KERN_ERR "DISASTER WAITING TO HAPPEN! Try to Stop it!\n");
+ return ata_error(drive, rq, __FUNCTION__);
}
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
- ret = ar->XXX_handler(drive, rq);
- spin_lock_irq(ch->lock);
- return ret;
+ /* will set handler for us */
+ return ar->XXX_handler(drive, rq);
}
}
} else {
@@ -456,221 +623,34 @@ static ide_startstop_t __do_request(struct ata_device *drive,
* FIXME: Handle the alternateives by a command type.
*/
+ /* FIXME: ATA_OP_CONTINUES? --bzolnier */
+ /* Not started a request - BUG() ot ATA_OP_FINISHED to avoid lockup ? - alat*/
if (!drive->using_dma)
- return ide_started;
+ return ATA_OP_CONTINUES;
/* for dma commands we don't set the handler */
- if (ar->cmd == WIN_WRITEDMA ||
- ar->cmd == WIN_WRITEDMA_EXT ||
- ar->cmd == WIN_READDMA ||
- ar->cmd == WIN_READDMA_EXT)
+ if (cmd == WIN_WRITEDMA ||
+ cmd == WIN_WRITEDMA_EXT ||
+ cmd == WIN_READDMA ||
+ cmd == WIN_READDMA_EXT)
return udma_init(drive, rq);
#ifdef CONFIG_BLK_DEV_IDE_TCQ
- else if (ar->cmd == WIN_WRITEDMA_QUEUED ||
- ar->cmd == WIN_WRITEDMA_QUEUED_EXT ||
- ar->cmd == WIN_READDMA_QUEUED ||
- ar->cmd == WIN_READDMA_QUEUED_EXT)
+ else if (cmd == WIN_WRITEDMA_QUEUED ||
+ cmd == WIN_WRITEDMA_QUEUED_EXT ||
+ cmd == WIN_READDMA_QUEUED ||
+ cmd == WIN_READDMA_QUEUED_EXT)
return udma_tcq_init(drive, rq);
#endif
else {
- printk(KERN_ERR "%s: unknown command %x\n", __FUNCTION__, ar->cmd);
- return ide_stopped;
- }
- }
-
- return ide_started;
-}
-
-/*
- * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
- * otherwise, to address sectors. It also takes care of issuing special
- * DRIVE_CMDs.
- *
- * Channel lock should be held.
- */
-static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct request *rq, sector_t block)
-{
- struct ata_taskfile args;
- unsigned int sectors;
-
- /* This issues a special drive command.
- */
- if (rq->flags & REQ_SPECIAL)
- return __do_request(drive, rq->special, rq);
-
- /* FIXME: this check doesn't make sense */
- if (!(rq->flags & REQ_CMD)) {
- blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
- __ata_end_request(drive, rq, 0, 0);
-
- return ide_stopped;
- }
-
- if (IS_PDC4030_DRIVE) {
- extern ide_startstop_t promise_do_request(struct ata_device *, struct request *, sector_t);
-
- return promise_do_request(drive, rq, block);
- }
-
- /*
- * start a tagged operation
- */
- if (drive->using_tcq) {
- int st = blk_queue_start_tag(&drive->queue, rq);
-
- if (ata_pending_commands(drive) > drive->max_depth)
- drive->max_depth = ata_pending_commands(drive);
- if (ata_pending_commands(drive) > drive->max_last_depth)
- drive->max_last_depth = ata_pending_commands(drive);
-
- if (st) {
- BUG_ON(!ata_pending_commands(drive));
-
- return ide_started;
- }
- }
-
- memset(&args, 0, sizeof(args));
- sectors = rq->nr_sectors;
- /* Dispatch depending up on the drive access method. */
- if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) {
- /* LBA 48 bit */
- /*
- * 268435455 == 137439 MB or 28bit limit
- * 320173056 == 163929 MB or 48bit addressing
- * 1073741822 == 549756 MB or 48bit addressing fake drive
- */
- if (sectors == 65536)
- sectors = 0;
-
- if (blk_rq_tagged(rq)) {
- args.taskfile.feature = sectors;
- args.hobfile.feature = sectors >> 8;
- args.taskfile.sector_count = rq->tag << 3;
- } else {
- args.taskfile.sector_count = sectors;
- args.hobfile.sector_count = sectors >> 8;
- }
-
- args.taskfile.sector_number = block; /* low lba */
- args.taskfile.low_cylinder = (block >>= 8); /* mid lba */
- args.taskfile.high_cylinder = (block >>= 8); /* hi lba */
- args.taskfile.device_head = drive->select.all;
-
- args.hobfile.sector_number = (block >>= 8); /* low lba */
- args.hobfile.low_cylinder = (block >>= 8); /* mid lba */
- args.hobfile.high_cylinder = (block >>= 8); /* hi lba */
- } else if (drive->select.b.lba) {
- /* LBA 28 bit */
- if (sectors == 256)
- sectors = 0;
-
- if (blk_rq_tagged(rq)) {
- args.taskfile.feature = sectors;
- args.taskfile.sector_count = rq->tag << 3;
- } else
- args.taskfile.sector_count = sectors;
-
- args.taskfile.sector_number = block;
- args.taskfile.low_cylinder = (block >>= 8);
- args.taskfile.high_cylinder = (block >>= 8);
- args.taskfile.device_head = ((block >> 8) & 0x0f);
- } else {
- /* CHS */
- unsigned int track = (block / drive->sect);
- unsigned int sect = (block % drive->sect) + 1;
- unsigned int head = (track % drive->head);
- unsigned int cyl = (track / drive->head);
-
- if (sectors == 256)
- sectors = 0;
-
- if (blk_rq_tagged(rq)) {
- args.taskfile.feature = sectors;
- args.taskfile.sector_count = rq->tag << 3;
- } else
- args.taskfile.sector_count = sectors;
-
- args.taskfile.sector_number = sect;
- args.taskfile.low_cylinder = cyl;
- args.taskfile.high_cylinder = (cyl>>8);
- args.taskfile.device_head = head;
- }
- args.taskfile.device_head |= drive->select.all;
-
- /*
- * Decode with physical ATA command to use and setup associated data.
- */
+ printk(KERN_ERR "%s: unknown command %x\n",
+ __FUNCTION__, cmd);
- if (rq_data_dir(rq) == READ) {
- args.command_type = IDE_DRIVE_TASK_IN;
- if (drive->addressing) {
- if (drive->using_tcq) {
- args.cmd = WIN_READDMA_QUEUED_EXT;
- } else if (drive->using_dma) {
- args.cmd = WIN_READDMA_EXT;
- } else if (drive->mult_count) {
- args.XXX_handler = task_mulin_intr;
- args.cmd = WIN_MULTREAD_EXT;
- } else {
- args.XXX_handler = task_in_intr;
- args.cmd = WIN_READ_EXT;
- }
- } else {
- if (drive->using_tcq) {
- args.cmd = WIN_READDMA_QUEUED;
- } else if (drive->using_dma) {
- args.cmd = WIN_READDMA;
- } else if (drive->mult_count) {
- /* FIXME : Shouldn't this be task_mulin_intr?! */
- args.XXX_handler = task_in_intr;
- args.cmd = WIN_MULTREAD;
- } else {
- args.XXX_handler = task_in_intr;
- args.cmd = WIN_READ;
- }
- }
- } else {
- args.command_type = IDE_DRIVE_TASK_RAW_WRITE;
- if (drive->addressing) {
- if (drive->using_tcq) {
- args.cmd = WIN_WRITEDMA_QUEUED_EXT;
- } else if (drive->using_dma) {
- args.cmd = WIN_WRITEDMA_EXT;
- } else if (drive->mult_count) {
- args.XXX_handler = task_mulout_intr;
- args.cmd = WIN_MULTWRITE_EXT;
- } else {
- args.XXX_handler = task_out_intr;
- args.cmd = WIN_WRITE_EXT;
- }
- } else {
- if (drive->using_tcq) {
- args.cmd = WIN_WRITEDMA_QUEUED;
- } else if (drive->using_dma) {
- args.cmd = WIN_WRITEDMA;
- } else if (drive->mult_count) {
- args.XXX_handler = task_mulout_intr;
- args.cmd = WIN_MULTWRITE;
- } else {
- args.XXX_handler = task_out_intr;
- args.cmd = WIN_WRITE;
- }
+ return ATA_OP_FINISHED;
}
}
-
-#ifdef DEBUG
- printk("%s: %sing: ", drive->name,
- (rq_data_dir(rq)==READ) ? "read" : "writ");
- if (lba) printk("LBAsect=%lld, ", block);
- else printk("CHS=%d/%d/%d, ", cyl, head, sect);
- printk("sectors=%ld, ", rq->nr_sectors);
- printk("buffer=%p\n", rq->buffer);
-#endif
- rq->special = &args;
-
- return __do_request(drive, &args, rq);
+ /* not reached */
+ return ATA_OP_CONTINUES;
}
static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_device *drive)
@@ -689,7 +669,7 @@ static int idedisk_open(struct inode *inode, struct file *__fp, struct ata_devic
memset(&args, 0, sizeof(args));
args.cmd = WIN_DOORLOCK;
- if (ide_raw_taskfile(drive, &args))
+ if (ide_raw_taskfile(drive, &args, NULL))
drive->doorlocking = 0;
}
}
@@ -708,7 +688,7 @@ static int flush_cache(struct ata_device *drive)
else
args.cmd = WIN_FLUSH_CACHE;
- return ide_raw_taskfile(drive, &args);
+ return ide_raw_taskfile(drive, &args, NULL);
}
static void idedisk_release(struct inode *inode, struct file *filp, struct ata_device *drive)
@@ -722,7 +702,7 @@ static void idedisk_release(struct inode *inode, struct file *filp, struct ata_d
memset(&args, 0, sizeof(args));
args.cmd = WIN_DOORUNLOCK;
- if (ide_raw_taskfile(drive, &args))
+ if (ide_raw_taskfile(drive, &args, NULL))
drive->doorlocking = 0;
}
}
@@ -769,7 +749,7 @@ static int set_multcount(struct ata_device *drive, int arg)
memset(&args, 0, sizeof(args));
args.taskfile.sector_count = arg;
args.cmd = WIN_SETMULT;
- if (!ide_raw_taskfile(drive, &args)) {
+ if (!ide_raw_taskfile(drive, &args, NULL)) {
/* all went well track this setting as valid */
drive->mult_count = arg;
@@ -798,7 +778,7 @@ static int write_cache(struct ata_device *drive, int arg)
memset(&args, 0, sizeof(args));
args.taskfile.feature = (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
args.cmd = WIN_SETFEATURES;
- ide_raw_taskfile(drive, &args);
+ ide_raw_taskfile(drive, &args, NULL);
drive->wcache = arg;
@@ -811,7 +791,7 @@ static int idedisk_standby(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.cmd = WIN_STANDBYNOW1;
- return ide_raw_taskfile(drive, &args);
+ return ide_raw_taskfile(drive, &args, NULL);
}
static int set_acoustic(struct ata_device *drive, int arg)
@@ -822,7 +802,7 @@ static int set_acoustic(struct ata_device *drive, int arg)
args.taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
args.taskfile.sector_count = arg;
args.cmd = WIN_SETFEATURES;
- ide_raw_taskfile(drive, &args);
+ ide_raw_taskfile(drive, &args, NULL);
drive->acoustic = arg;
@@ -942,7 +922,7 @@ static unsigned long native_max_address(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40;
args.cmd = WIN_READ_NATIVE_MAX;
- ide_raw_taskfile(drive, &args);
+ ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */
if (!(drive->status & ERR_STAT)) {
@@ -964,10 +944,9 @@ static u64 native_max_address_ext(struct ata_device *drive)
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
-
args.taskfile.device_head = 0x40;
args.cmd = WIN_READ_NATIVE_MAX_EXT;
- ide_raw_taskfile(drive, &args);
+ ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */
if (!(drive->status & ERR_STAT)) {
@@ -1005,7 +984,7 @@ static sector_t set_max_address(struct ata_device *drive, sector_t addr_req)
args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
args.cmd = WIN_SET_MAX;
- ide_raw_taskfile(drive, &args);
+ ide_raw_taskfile(drive, &args, NULL);
/* if OK, read new maximum address value */
if (!(drive->status & ERR_STAT)) {
@@ -1038,7 +1017,7 @@ static u64 set_max_address_ext(struct ata_device *drive, u64 addr_req)
args.hobfile.high_cylinder = (addr_req >>= 8);
args.hobfile.device_head = 0x40;
- ide_raw_taskfile(drive, &args);
+ ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */
if (!(drive->status & ERR_STAT)) {
@@ -1422,7 +1401,12 @@ static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct f
#ifdef CONFIG_BLK_DEV_IDE_TCQ
case HDIO_GET_QDMA: {
- u8 val = drive->using_tcq;
+ /* Foolup hdparm 0 means off 1 on -alat */
+ /* FIXME: hdparm have only -Q do we need something like:
+ * hdparm -q 1/0 - TCQ on/off
+ * hdparm -Q 1-MAX - TCQ queue_depth ?
+ */
+ u8 val = ( drive->using_tcq ? drive->queue_depth : 0 );
if (put_user(val, (u8 *) arg))
return -EFAULT;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 35fbe0aa5b86..83cb749e243f 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -315,270 +315,6 @@ typedef struct {
#define IDEFLOPPY_ERROR_GENERAL 101
/*
- * The ATAPI Status Register.
- */
-typedef union {
- unsigned all :8;
- struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned check :1; /* Error occurred */
- unsigned idx :1; /* Reserved */
- unsigned corr :1; /* Correctable error occurred */
- unsigned drq :1; /* Data is request by the device */
- unsigned dsc :1; /* Media access command finished */
- unsigned reserved5 :1; /* Reserved */
- unsigned drdy :1; /* Ignored for ATAPI commands (ready to accept ATA command) */
- unsigned bsy :1; /* The device has access to the command block */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned bsy :1; /* The device has access to the command block */
- unsigned drdy :1; /* Ignored for ATAPI commands (ready to accept ATA command) */
- unsigned reserved5 :1; /* Reserved */
- unsigned dsc :1; /* Media access command finished */
- unsigned drq :1; /* Data is request by the device */
- unsigned corr :1; /* Correctable error occurred */
- unsigned idx :1; /* Reserved */
- unsigned check :1; /* Error occurred */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
- } b;
-} idefloppy_status_reg_t;
-
-/*
- * The ATAPI error register.
- */
-typedef union {
- unsigned all :8;
- struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned ili :1; /* Illegal Length Indication */
- unsigned eom :1; /* End Of Media Detected */
- unsigned abrt :1; /* Aborted command - As defined by ATA */
- unsigned mcr :1; /* Media Change Requested - As defined by ATA */
- unsigned sense_key :4; /* Sense key of the last failed packet command */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned sense_key :4; /* Sense key of the last failed packet command */
- unsigned mcr :1; /* Media Change Requested - As defined by ATA */
- unsigned abrt :1; /* Aborted command - As defined by ATA */
- unsigned eom :1; /* End Of Media Detected */
- unsigned ili :1; /* Illegal Length Indication */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
- } b;
-} idefloppy_error_reg_t;
-
-/*
- * ATAPI Feature Register
- */
-typedef union {
- unsigned all :8;
- struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned dma :1; /* Using DMA or PIO */
- unsigned reserved321 :3; /* Reserved */
- unsigned reserved654 :3; /* Reserved (Tag Type) */
- unsigned reserved7 :1; /* Reserved */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned reserved7 :1; /* Reserved */
- unsigned reserved654 :3; /* Reserved (Tag Type) */
- unsigned reserved321 :3; /* Reserved */
- unsigned dma :1; /* Using DMA or PIO */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
- } b;
-} idefloppy_feature_reg_t;
-
-/*
- * ATAPI Byte Count Register.
- */
-typedef union {
- unsigned all :16;
- struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned low :8; /* LSB */
- unsigned high :8; /* MSB */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned high :8; /* MSB */
- unsigned low :8; /* LSB */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
- } b;
-} idefloppy_bcount_reg_t;
-
-/*
- * ATAPI Interrupt Reason Register.
- */
-typedef union {
- unsigned all :8;
- struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned cod :1; /* Information transferred is command (1) or data (0) */
- unsigned io :1; /* The device requests us to read (1) or write (0) */
- unsigned reserved :6; /* Reserved */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned reserved :6; /* Reserved */
- unsigned io :1; /* The device requests us to read (1) or write (0) */
- unsigned cod :1; /* Information transferred is command (1) or data (0) */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
- } b;
-} idefloppy_ireason_reg_t;
-
-/*
- * ATAPI floppy Drive Select Register
- */
-typedef union {
- unsigned all :8;
- struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned sam_lun :3; /* Logical unit number */
- unsigned reserved3 :1; /* Reserved */
- unsigned drv :1; /* The responding drive will be drive 0 (0) or drive 1 (1) */
- unsigned one5 :1; /* Should be set to 1 */
- unsigned reserved6 :1; /* Reserved */
- unsigned one7 :1; /* Should be set to 1 */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned one7 :1; /* Should be set to 1 */
- unsigned reserved6 :1; /* Reserved */
- unsigned one5 :1; /* Should be set to 1 */
- unsigned drv :1; /* The responding drive will be drive 0 (0) or drive 1 (1) */
- unsigned reserved3 :1; /* Reserved */
- unsigned sam_lun :3; /* Logical unit number */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
- } b;
-} idefloppy_drivesel_reg_t;
-
-/*
- * ATAPI Device Control Register
- */
-typedef union {
- unsigned all :8;
- struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned zero0 :1; /* Should be set to zero */
- unsigned nien :1; /* Device interrupt is disabled (1) or enabled (0) */
- unsigned srst :1; /* ATA software reset. ATAPI devices should use the new ATAPI srst. */
- unsigned one3 :1; /* Should be set to 1 */
- unsigned reserved4567 :4; /* Reserved */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned reserved4567 :4; /* Reserved */
- unsigned one3 :1; /* Should be set to 1 */
- unsigned srst :1; /* ATA software reset. ATAPI devices should use the new ATAPI srst. */
- unsigned nien :1; /* Device interrupt is disabled (1) or enabled (0) */
- unsigned zero0 :1; /* Should be set to zero */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
- } b;
-} idefloppy_control_reg_t;
-
-/*
- * The following is used to format the general configuration word of
- * the ATAPI IDENTIFY DEVICE command.
- */
-struct idefloppy_id_gcw {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned packet_size :2; /* Packet Size */
- unsigned reserved234 :3; /* Reserved */
- unsigned drq_type :2; /* Command packet DRQ type */
- unsigned removable :1; /* Removable media */
- unsigned device_type :5; /* Device type */
- unsigned reserved13 :1; /* Reserved */
- unsigned protocol :2; /* Protocol type */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned protocol :2; /* Protocol type */
- unsigned reserved13 :1; /* Reserved */
- unsigned device_type :5; /* Device type */
- unsigned removable :1; /* Removable media */
- unsigned drq_type :2; /* Command packet DRQ type */
- unsigned reserved234 :3; /* Reserved */
- unsigned packet_size :2; /* Packet Size */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
-};
-
-/*
- * INQUIRY packet command - Data Format
- */
-typedef struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned device_type :5; /* Peripheral Device Type */
- unsigned reserved0_765 :3; /* Peripheral Qualifier - Reserved */
- unsigned reserved1_6t0 :7; /* Reserved */
- unsigned rmb :1; /* Removable Medium Bit */
- unsigned ansi_version :3; /* ANSI Version */
- unsigned ecma_version :3; /* ECMA Version */
- unsigned iso_version :2; /* ISO Version */
- unsigned response_format :4; /* Response Data Format */
- unsigned reserved3_45 :2; /* Reserved */
- unsigned reserved3_6 :1; /* TrmIOP - Reserved */
- unsigned reserved3_7 :1; /* AENC - Reserved */
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned reserved0_765 :3; /* Peripheral Qualifier - Reserved */
- unsigned device_type :5; /* Peripheral Device Type */
- unsigned rmb :1; /* Removable Medium Bit */
- unsigned reserved1_6t0 :7; /* Reserved */
- unsigned iso_version :2; /* ISO Version */
- unsigned ecma_version :3; /* ECMA Version */
- unsigned ansi_version :3; /* ANSI Version */
- unsigned reserved3_7 :1; /* AENC - Reserved */
- unsigned reserved3_6 :1; /* TrmIOP - Reserved */
- unsigned reserved3_45 :2; /* Reserved */
- unsigned response_format :4; /* Response Data Format */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
- u8 additional_length; /* Additional Length (total_length-4) */
- u8 rsv5, rsv6, rsv7; /* Reserved */
- u8 vendor_id[8]; /* Vendor Identification */
- u8 product_id[16]; /* Product Identification */
- u8 revision_level[4]; /* Revision Level */
- u8 vendor_specific[20]; /* Vendor Specific - Optional */
- u8 reserved56t95[40]; /* Reserved - Optional */
- /* Additional information may be returned */
-} idefloppy_inquiry_result_t;
-
-/*
- * REQUEST SENSE packet command result - Data Format.
- */
-typedef struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- unsigned error_code :7; /* Current error (0x70) */
- unsigned valid :1; /* The information field conforms to SFF-8070i */
- u8 reserved1 :8; /* Reserved */
- unsigned sense_key :4; /* Sense Key */
- unsigned reserved2_4 :1; /* Reserved */
- unsigned ili :1; /* Incorrect Length Indicator */
- unsigned reserved2_67 :2;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- unsigned valid :1; /* The information field conforms to SFF-8070i */
- unsigned error_code :7; /* Current error (0x70) */
- u8 reserved1 :8; /* Reserved */
- unsigned reserved2_67 :2;
- unsigned ili :1; /* Incorrect Length Indicator */
- unsigned reserved2_4 :1; /* Reserved */
- unsigned sense_key :4; /* Sense Key */
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
- u32 information __attribute__ ((packed));
- u8 asl; /* Additional sense length (n-7) */
- u32 command_specific; /* Additional command specific information */
- u8 asc; /* Additional Sense Code */
- u8 ascq; /* Additional Sense Code Qualifier */
- u8 replaceable_unit_code; /* Field Replaceable Unit Code */
- u8 sksv[3];
- u8 pad[2]; /* Padding to 20 bytes */
-} idefloppy_request_sense_result_t;
-
-/*
* Pages of the SELECT SENSE / MODE SENSE packet commands.
*/
#define IDEFLOPPY_CAPABILITIES_PAGE 0x1b
@@ -602,9 +338,6 @@ typedef struct {
u8 reserved[4];
} idefloppy_mode_parameter_header_t;
-#define IDEFLOPPY_MIN(a,b) ((a)<(b) ? (a):(b))
-#define IDEFLOPPY_MAX(a,b) ((a)>(b) ? (a):(b))
-
/*
* idefloppy_end_request is used to finish servicing a request.
*
@@ -613,6 +346,8 @@ typedef struct {
*/
static int idefloppy_end_request(struct ata_device *drive, struct request *rq, int uptodate)
{
+ unsigned long flags;
+ struct ata_channel *ch = drive->channel;
idefloppy_floppy_t *floppy = drive->driver_data;
int error;
@@ -632,15 +367,19 @@ static int idefloppy_end_request(struct ata_device *drive, struct request *rq, i
return 0;
if (!(rq->flags & REQ_SPECIAL)) {
- ata_end_request(drive, rq, uptodate);
+ __ata_end_request(drive, rq, uptodate, 0);
return 0;
}
+ spin_lock_irqsave(ch->lock, flags);
+
rq->errors = error;
blkdev_dequeue_request(rq);
drive->rq = NULL;
end_that_request_last(rq);
+ spin_unlock_irqrestore(ch->lock, flags);
+
return 0;
}
@@ -663,7 +402,7 @@ static void idefloppy_input_buffers(struct ata_device *drive, struct request *rq
atapi_discard_data(drive, bcount);
return;
}
- count = IDEFLOPPY_MIN(bio->bi_size - pc->b_count, bcount);
+ count = min_t(unsigned int, bio->bi_size - pc->b_count, bcount);
atapi_read(drive, bio_data(bio) + pc->b_count, count);
bcount -= count; pc->b_count += count;
}
@@ -690,7 +429,7 @@ static void idefloppy_output_buffers(struct ata_device *drive, struct request *r
atapi_write_zeros (drive, bcount);
return;
}
- count = IDEFLOPPY_MIN(pc->b_count, bcount);
+ count = min_t(unsigned int, pc->b_count, bcount);
atapi_write(drive, pc->b_data, count);
bcount -= count; pc->b_data += count; pc->b_count -= count;
}
@@ -743,13 +482,13 @@ static struct request *idefloppy_next_rq_storage(struct ata_device *drive)
* idefloppy_analyze_error is called on each failed packet command retry
* to analyze the request sense.
*/
-static void idefloppy_analyze_error(struct ata_device *drive, idefloppy_request_sense_result_t *result)
+static void idefloppy_analyze_error(struct ata_device *drive, atapi_request_sense_result_t *result)
{
idefloppy_floppy_t *floppy = drive->driver_data;
floppy->sense_key = result->sense_key; floppy->asc = result->asc; floppy->ascq = result->ascq;
- floppy->progress_indication= result->sksv[0] & 0x80 ?
- (unsigned short)get_unaligned((u16 *)(result->sksv+1)):0x10000;
+ floppy->progress_indication= result->sksv ?
+ (unsigned short)get_unaligned((u16 *)(result->sk_specific)):0x10000;
#if IDEFLOPPY_DEBUG_LOG
if (floppy->failed_pc)
printk (KERN_INFO "ide-floppy: pc = %x, sense key = %x, asc = %x, ascq = %x\n",floppy->failed_pc->c[0],result->sense_key,result->asc,result->ascq);
@@ -766,7 +505,7 @@ static void idefloppy_request_sense_callback(struct ata_device *drive, struct re
printk (KERN_INFO "ide-floppy: Reached idefloppy_request_sense_callback\n");
#endif
if (!floppy->pc->error) {
- idefloppy_analyze_error(drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer);
+ idefloppy_analyze_error(drive,(atapi_request_sense_result_t *) floppy->pc->buffer);
idefloppy_end_request(drive, rq, 1);
} else {
printk (KERN_ERR "Error in REQUEST SENSE itself - Aborting request!\n");
@@ -806,7 +545,7 @@ static void idefloppy_retry_pc(struct ata_device *drive)
{
struct atapi_packet_command *pc;
struct request *rq;
- idefloppy_error_reg_t error;
+ atapi_error_reg_t error;
error.all = IN_BYTE(IDE_ERROR_REG);
pc = idefloppy_next_pc_storage(drive);
@@ -821,12 +560,10 @@ static void idefloppy_retry_pc(struct ata_device *drive)
*/
static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
idefloppy_floppy_t *floppy = drive->driver_data;
- idefloppy_status_reg_t status;
- idefloppy_bcount_reg_t bcount;
- idefloppy_ireason_reg_t ireason;
+ atapi_status_reg_t status;
+ atapi_bcount_reg_t bcount;
+ atapi_ireason_reg_t ireason;
struct atapi_packet_command *pc = floppy->pc;
unsigned int temp;
@@ -866,46 +603,40 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
rq->errors++;
if (pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
printk (KERN_ERR "ide-floppy: I/O error in request sense command\n");
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
idefloppy_retry_pc (drive); /* Retry operation */
- return ide_stopped; /* queued, but not started */
+ return ATA_OP_FINISHED; /* queued, but not started */
}
pc->error = 0;
if (floppy->failed_pc == pc)
floppy->failed_pc=NULL;
pc->callback(drive, rq); /* Command finished - Call the callback function */
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
printk (KERN_ERR "ide-floppy: The floppy wants to issue more interrupts in DMA mode\n");
udma_enable(drive, 0, 1);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
#endif
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
- spin_lock_irqsave(ch->lock, flags);
bcount.b.high=IN_BYTE (IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */
bcount.b.low=IN_BYTE (IDE_BCOUNTL_REG); /* on this interrupt */
ireason.all=IN_BYTE (IDE_IREASON_REG);
if (ireason.b.cod) {
- spin_unlock_irqrestore(ch->lock, flags);
-
printk (KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n");
- return ide_stopped;
+
+ return ATA_OP_FINISHED;
}
if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */
- spin_unlock_irqrestore(ch->lock, flags);
-
printk (KERN_ERR "ide-floppy: We wanted to %s, ", ireason.b.io ? "Write":"Read");
printk (KERN_ERR "but the floppy wants us to %s !\n",ireason.b.io ? "Read":"Write");
- return ide_stopped;
+
+ return ATA_OP_FINISHED;
}
if (!test_bit(PC_WRITING, &pc->flags)) { /* Reading - Check that we have enough space */
temp = pc->actually_transferred + bcount.all;
@@ -915,9 +646,8 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
atapi_discard_data (drive,bcount.all);
ata_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
#if IDEFLOPPY_DEBUG_LOG
printk (KERN_NOTICE "ide-floppy: The floppy wants to send us more data than expected - allowing transfer\n");
@@ -939,9 +669,8 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
pc->current_position+=bcount.all;
ata_set_handler(drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
/*
@@ -951,34 +680,27 @@ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct reques
*/
static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
- ide_startstop_t startstop;
idefloppy_floppy_t *floppy = drive->driver_data;
- idefloppy_ireason_reg_t ireason;
+ atapi_ireason_reg_t ireason;
int ret;
- /* FIXME: Move this lock upwards.
- */
- spin_lock_irqsave(ch->lock, flags);
- if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
- WAIT_READY, rq, &startstop)) {
+ ret = ata_status_poll(drive, DRQ_STAT, BUSY_STAT, WAIT_READY, rq);
+ if (ret != ATA_OP_READY) {
printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
- ret = startstop;
- } else {
- ireason.all=IN_BYTE (IDE_IREASON_REG);
+ return ret;
+ }
- if (!ireason.b.cod || ireason.b.io) {
- printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
- ret = ide_stopped;
- } else {
- ata_set_handler (drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */
- atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */
- ret = ide_started;
- }
+ ireason.all = IN_BYTE(IDE_IREASON_REG);
+
+ if (!ireason.b.cod || ireason.b.io) {
+ printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
+ ret = ATA_OP_FINISHED;
+ } else {
+ ata_set_handler(drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* Set the interrupt routine */
+ atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */
+ ret = ATA_OP_CONTINUES;
}
- spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
@@ -996,39 +718,35 @@ static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct re
* packet, we schedule the packet transfer to occur about 2-3 ticks
* later in transfer_pc2.
*/
-static int idefloppy_transfer_pc2(struct ata_device *drive, struct request *__rq)
+static ide_startstop_t idefloppy_transfer_pc2(struct ata_device *drive, struct request *__rq, unsigned long *wait)
{
idefloppy_floppy_t *floppy = drive->driver_data;
atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */
- return IDEFLOPPY_WAIT_CMD; /* Timeout for the packet command */
+ *wait = IDEFLOPPY_WAIT_CMD; /* Timeout for the packet command */
+
+ return ATA_OP_CONTINUES;
}
static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
idefloppy_floppy_t *floppy = drive->driver_data;
ide_startstop_t startstop;
- idefloppy_ireason_reg_t ireason;
+ atapi_ireason_reg_t ireason;
int ret;
- if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
- WAIT_READY, rq, &startstop)) {
+ ret = ata_status_poll(drive, DRQ_STAT, BUSY_STAT, WAIT_READY, rq);
+ if (ret != ATA_OP_READY) {
printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n");
- return startstop;
+ return ret;
}
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
+ ireason.all = IN_BYTE(IDE_IREASON_REG);
- spin_lock_irqsave(ch->lock, flags);
- ireason.all=IN_BYTE(IDE_IREASON_REG);
if (!ireason.b.cod || ireason.b.io) {
printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
- ret = ide_stopped;
+ ret = ATA_OP_FINISHED;
} else {
/*
@@ -1043,9 +761,8 @@ static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct r
idefloppy_pc_intr, /* service routine for packet command */
floppy->ticks, /* wait this long before "failing" */
idefloppy_transfer_pc2); /* fail == transfer_pc2 */
- ret = ide_started;
+ ret = ATA_OP_CONTINUES;
}
- spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
@@ -1057,7 +774,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
struct atapi_packet_command *pc)
{
idefloppy_floppy_t *floppy = drive->driver_data;
- idefloppy_bcount_reg_t bcount;
+ atapi_bcount_reg_t bcount;
int dma_ok = 0;
ata_handler_t *pkt_xfer_routine;
@@ -1086,7 +803,7 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
}
floppy->failed_pc = NULL;
pc->callback(drive, rq);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
#if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "Retry number - %d\n",pc->retries);
@@ -1126,19 +843,10 @@ static ide_startstop_t idefloppy_issue_pc(struct ata_device *drive, struct reque
}
if (test_bit(IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
-
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
} else {
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
return pkt_xfer_routine(drive, rq);
@@ -1277,10 +985,8 @@ static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy,
*/
static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
- struct ata_channel *ch = drive->channel;
idefloppy_floppy_t *floppy = drive->driver_data;
struct atapi_packet_command *pc;
- int ret;
#if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors);
@@ -1294,22 +1000,17 @@ static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct req
else
printk (KERN_ERR "ide-floppy: %s: I/O error\n", drive->name);
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
idefloppy_end_request(drive, rq, 0);
- spin_lock_irq(ch->lock);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
if (rq->flags & REQ_CMD) {
if (rq->sector % floppy->bs_factor || rq->nr_sectors % floppy->bs_factor) {
printk ("%s: unsupported r/w request size\n", drive->name);
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
+
idefloppy_end_request(drive, rq, 0);
- spin_lock_irq(ch->lock);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
pc = idefloppy_next_pc_storage(drive);
idefloppy_create_rw_cmd (floppy, pc, rq, block);
@@ -1318,20 +1019,13 @@ static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct req
pc = (struct atapi_packet_command *) rq->buffer;
} else {
blk_dump_rq_flags(rq, "ide-floppy: unsupported command in queue");
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
+
idefloppy_end_request(drive, rq, 0);
- spin_lock_irq(ch->lock);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
- ret = idefloppy_issue_pc(drive, rq, pc);
- spin_lock_irq(ch->lock);
-
- return ret;
+ return idefloppy_issue_pc(drive, rq, pc);
}
/*
@@ -1655,7 +1349,7 @@ static int idefloppy_get_format_progress(struct ata_device *drive,
}
else
{
- idefloppy_status_reg_t status;
+ atapi_status_reg_t status;
unsigned long flags;
__save_flags(flags);
@@ -1861,7 +1555,7 @@ static unsigned long idefloppy_capacity(struct ata_device *drive)
*/
static int idefloppy_identify_device(struct ata_device *drive,struct hd_driveid *id)
{
- struct idefloppy_id_gcw gcw;
+ struct atapi_id_gcw gcw;
#if IDEFLOPPY_DEBUG_INFO
unsigned short mask,i;
char buffer[80];
@@ -1976,7 +1670,7 @@ static int idefloppy_identify_device(struct ata_device *drive,struct hd_driveid
*/
static void idefloppy_setup(struct ata_device *drive, idefloppy_floppy_t *floppy)
{
- struct idefloppy_id_gcw gcw;
+ struct atapi_id_gcw gcw;
int i;
*((unsigned short *) &gcw) = drive->id->config;
diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c
index c609aa7e7b78..0b6fe40cd806 100644
--- a/drivers/ide/ide-pci.c
+++ b/drivers/ide/ide-pci.c
@@ -257,24 +257,13 @@ controller_ok:
if (d->flags & ATA_F_NODMA)
goto no_dma;
- /* Check whatever this interface is UDMA4 mode capable. */
- if (ch->udma_four) {
+ if (ch->udma_four)
printk("%s: warning: ATA-66/100 forced bit set!\n", dev->name);
- } else {
- if (d->ata66_check)
- ch->udma_four = d->ata66_check(ch);
- }
#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* Setup DMA transfers on the channel.
*/
- if (d->flags & ATA_F_NOADMA)
- autodma = 0;
-
- if (autodma)
- ch->autodma = 1;
-
if (!((d->flags & ATA_F_DMA) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))))
goto no_dma;
/*
@@ -324,6 +313,10 @@ controller_ok:
* already enabled by the primary channel run.
*/
pci_set_master(dev);
+
+ if (autodma)
+ ch->autodma = 1;
+
if (d->init_dma)
d->init_dma(ch, dma_base);
else
@@ -335,6 +328,11 @@ no_dma:
if (d->init_channel)
d->init_channel(ch);
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ if ((d->flags & ATA_F_NOADMA) || noautodma)
+ ch->autodma = 0;
+#endif
+
return 0;
}
diff --git a/drivers/ide/ide-pmac.c b/drivers/ide/ide-pmac.c
index 9aa76224a54c..b66b002b7223 100644
--- a/drivers/ide/ide-pmac.c
+++ b/drivers/ide/ide-pmac.c
@@ -256,11 +256,11 @@ struct {
static void pmac_ide_setup_dma(struct device_node *np, int ix);
static void pmac_udma_enable(struct ata_device *drive, int on, int verbose);
-static int pmac_udma_start(struct ata_device *drive, struct request *rq);
+static void pmac_udma_start(struct ata_device *drive, struct request *rq);
static int pmac_udma_stop(struct ata_device *drive);
static int pmac_udma_init(struct ata_device *drive, struct request *rq);
static int pmac_udma_irq_status(struct ata_device *drive);
-static int pmac_udma_setup(struct ata_device *drive);
+static int pmac_udma_setup(struct ata_device *drive, int map);
static int pmac_ide_build_dmatable(struct ata_device *drive, struct request *rq, int ix, int wr);
static int pmac_ide_tune_chipset(struct ata_device *drive, byte speed);
static void pmac_ide_tuneproc(struct ata_device *drive, byte pio);
@@ -1340,7 +1340,7 @@ static void pmac_udma_enable(struct ata_device *drive, int on, int verbose)
ide_toggle_bounce(drive, 0);
}
-static int pmac_udma_start(struct ata_device *drive, struct request *rq)
+static void pmac_udma_start(struct ata_device *drive, struct request *rq)
{
int ix, ata4;
volatile struct dbdma_regs *dma;
@@ -1350,7 +1350,7 @@ static int pmac_udma_start(struct ata_device *drive, struct request *rq)
*/
ix = pmac_ide_find(drive);
if (ix < 0)
- return ide_stopped;
+ return;
dma = pmac_ide[ix].dma_regs;
ata4 = (pmac_ide[ix].kind == controller_kl_ata4 ||
@@ -1360,7 +1360,7 @@ static int pmac_udma_start(struct ata_device *drive, struct request *rq)
/* Make sure it gets to the controller right now */
(void)in_le32(&dma->control);
- return ide_started;
+ return;
}
static int pmac_udma_stop(struct ata_device *drive)
@@ -1397,7 +1397,7 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq)
*/
ix = pmac_ide_find(drive);
if (ix < 0)
- return ide_stopped;
+ return ATA_OP_FINISHED;
if (rq_data_dir(rq) == READ)
reading = 1;
@@ -1409,7 +1409,7 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq)
pmac_ide[ix].kind == controller_kl_ata4_80);
if (!pmac_ide_build_dmatable(drive, rq, ix, !reading))
- return ide_stopped;
+ return ATA_OP_FINISHED;
/* Apple adds 60ns to wrDataSetup on reads */
if (ata4 && (pmac_ide[ix].timings[unit] & TR_66_UDMA_EN)) {
out_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE),
@@ -1419,7 +1419,7 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq)
}
if (drive->type != ATA_DISK)
- return ide_started;
+ return ATA_OP_CONTINUES;
ata_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
if ((rq->flags & REQ_SPECIAL) &&
@@ -1435,7 +1435,7 @@ static int pmac_udma_init(struct ata_device *drive, struct request *rq)
udma_start(drive, rq);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
/*
@@ -1491,14 +1491,14 @@ static int pmac_udma_irq_status(struct ata_device *drive)
set_bit(IDE_DMA, drive->channel->active);
// if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
// printk(KERN_WARNING "ide%d, timeout waiting \
- for dbdma command stop\n", ix);
- return 1;
- }
+// for dbdma command stop\n", ix);
+// return 1;
+// }
udelay(1);
return 0;
}
-static int pmac_udma_setup(struct ata_device *drive)
+static int pmac_udma_setup(struct ata_device *drive, int map)
{
/* Change this to better match ide-dma.c */
pmac_ide_check_dma(drive);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index ed6b83e11b98..36b8fa16ab52 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -10,6 +10,10 @@
*/
/*
+ * BIG FAT FIXME: clean tape->spinlock locking --bzolnier
+ */
+
+/*
* IDE ATAPI streaming tape driver.
*
* This driver is a part of the Linux ide driver and works in co-operation
@@ -771,32 +775,6 @@ typedef struct idetape_stage_s {
} idetape_stage_t;
/*
- * REQUEST SENSE packet command result - Data Format.
- */
-typedef struct {
- unsigned error_code :7; /* Current of deferred errors */
- unsigned valid :1; /* The information field conforms to QIC-157C */
- __u8 reserved1 :8; /* Segment Number - Reserved */
- unsigned sense_key :4; /* Sense Key */
- unsigned reserved2_4 :1; /* Reserved */
- unsigned ili :1; /* Incorrect Length Indicator */
- unsigned eom :1; /* End Of Medium */
- unsigned filemark :1; /* Filemark */
- __u32 information __attribute__ ((packed));
- __u8 asl; /* Additional sense length (n-7) */
- __u32 command_specific; /* Additional command specific information */
- __u8 asc; /* Additional Sense Code */
- __u8 ascq; /* Additional Sense Code Qualifier */
- __u8 replaceable_unit_code; /* Field Replaceable Unit Code */
- unsigned sk_specific1 :7; /* Sense Key Specific */
- unsigned sksv :1; /* Sense Key Specific information is valid */
- __u8 sk_specific2; /* Sense Key Specific */
- __u8 sk_specific3; /* Sense Key Specific */
- __u8 pad[2]; /* Padding to 20 bytes */
-} idetape_request_sense_result_t;
-
-
-/*
* Most of our global data which we need to save even as we leave the
* driver due to an interrupt or a timer event is stored in a variable
* of type idetape_tape_t, defined below.
@@ -920,7 +898,7 @@ typedef struct {
int avg_size;
int avg_speed;
- idetape_request_sense_result_t sense; /* last sense information */
+ atapi_request_sense_result_t sense; /* last sense information */
char vendor_id[10];
char product_id[18];
@@ -1124,101 +1102,6 @@ typedef struct {
#define IDETAPE_ERROR_EOD 103
/*
- * The ATAPI Status Register.
- */
-typedef union {
- unsigned all :8;
- struct {
- unsigned check :1; /* Error occurred */
- unsigned idx :1; /* Reserved */
- unsigned corr :1; /* Correctable error occurred */
- unsigned drq :1; /* Data is request by the device */
- unsigned dsc :1; /* Buffer availability / Media access command finished */
- unsigned reserved5 :1; /* Reserved */
- unsigned drdy :1; /* Ignored for ATAPI commands (ready to accept ATA command) */
- unsigned bsy :1; /* The device has access to the command block */
- } b;
-} idetape_status_reg_t;
-
-/*
- * The ATAPI error register.
- */
-typedef union {
- unsigned all :8;
- struct {
- unsigned ili :1; /* Illegal Length Indication */
- unsigned eom :1; /* End Of Media Detected */
- unsigned abrt :1; /* Aborted command - As defined by ATA */
- unsigned mcr :1; /* Media Change Requested - As defined by ATA */
- unsigned sense_key :4; /* Sense key of the last failed packet command */
- } b;
-} idetape_error_reg_t;
-
-/*
- * ATAPI Feature Register
- */
-typedef union {
- unsigned all :8;
- struct {
- unsigned dma :1; /* Using DMA or PIO */
- unsigned reserved321 :3; /* Reserved */
- unsigned reserved654 :3; /* Reserved (Tag Type) */
- unsigned reserved7 :1; /* Reserved */
- } b;
-} idetape_feature_reg_t;
-
-/*
- * ATAPI Byte Count Register.
- */
-typedef union {
- unsigned all :16;
- struct {
- unsigned low :8; /* LSB */
- unsigned high :8; /* MSB */
- } b;
-} idetape_bcount_reg_t;
-
-/*
- * ATAPI Interrupt Reason Register.
- */
-typedef union {
- unsigned all :8;
- struct {
- unsigned cod :1; /* Information transferred is command (1) or data (0) */
- unsigned io :1; /* The device requests us to read (1) or write (0) */
- unsigned reserved :6; /* Reserved */
- } b;
-} idetape_ireason_reg_t;
-
-/*
- * ATAPI Drive Select Register
- */
-typedef union {
- unsigned all :8;
- struct {
- unsigned sam_lun :4; /* Should be zero with ATAPI (not used) */
- unsigned drv :1; /* The responding drive will be drive 0 (0) or drive 1 (1) */
- unsigned one5 :1; /* Should be set to 1 */
- unsigned reserved6 :1; /* Reserved */
- unsigned one7 :1; /* Should be set to 1 */
- } b;
-} idetape_drivesel_reg_t;
-
-/*
- * ATAPI Device Control Register
- */
-typedef union {
- unsigned all :8;
- struct {
- unsigned zero0 :1; /* Should be set to zero */
- unsigned nien :1; /* Device interrupt is disabled (1) or enabled (0) */
- unsigned srst :1; /* ATA software reset. ATAPI devices should use the new ATAPI srst. */
- unsigned one3 :1; /* Should be set to 1 */
- unsigned reserved4567 :4; /* Reserved */
- } b;
-} idetape_control_reg_t;
-
-/*
* idetape_chrdev_t provides the link between out character device
* interface and our block device interface and the corresponding
* ata_device structure.
@@ -1228,45 +1111,6 @@ typedef struct {
} idetape_chrdev_t;
/*
- * The following is used to format the general configuration word of
- * the ATAPI IDENTIFY DEVICE command.
- */
-struct idetape_id_gcw {
- unsigned packet_size :2; /* Packet Size */
- unsigned reserved234 :3; /* Reserved */
- unsigned drq_type :2; /* Command packet DRQ type */
- unsigned removable :1; /* Removable media */
- unsigned device_type :5; /* Device type */
- unsigned reserved13 :1; /* Reserved */
- unsigned protocol :2; /* Protocol type */
-};
-
-/*
- * INQUIRY packet command - Data Format (From Table 6-8 of QIC-157C)
- */
-typedef struct {
- unsigned device_type :5; /* Peripheral Device Type */
- unsigned reserved0_765 :3; /* Peripheral Qualifier - Reserved */
- unsigned reserved1_6t0 :7; /* Reserved */
- unsigned rmb :1; /* Removable Medium Bit */
- unsigned ansi_version :3; /* ANSI Version */
- unsigned ecma_version :3; /* ECMA Version */
- unsigned iso_version :2; /* ISO Version */
- unsigned response_format :4; /* Response Data Format */
- unsigned reserved3_45 :2; /* Reserved */
- unsigned reserved3_6 :1; /* TrmIOP - Reserved */
- unsigned reserved3_7 :1; /* AENC - Reserved */
- __u8 additional_length; /* Additional Length (total_length-4) */
- __u8 rsv5, rsv6, rsv7; /* Reserved */
- __u8 vendor_id[8]; /* Vendor Identification */
- __u8 product_id[16]; /* Product Identification */
- __u8 revision_level[4]; /* Revision Level */
- __u8 vendor_specific[20]; /* Vendor Specific - Optional */
- __u8 reserved56t95[40]; /* Reserved - Optional */
- /* Additional information may be returned */
-} idetape_inquiry_result_t;
-
-/*
* READ POSITION packet command - Data Format (From Table 6-57)
*/
typedef struct {
@@ -1574,7 +1418,7 @@ static struct request *idetape_next_rq_storage(struct ata_device *drive)
* to analyze the request sense. We currently do not utilize this
* information.
*/
-static void idetape_analyze_error(struct ata_device *drive, idetape_request_sense_result_t *result)
+static void idetape_analyze_error(struct ata_device *drive, atapi_request_sense_result_t *result)
{
idetape_tape_t *tape = drive->driver_data;
struct atapi_packet_command *pc = tape->failed_pc;
@@ -1778,7 +1622,7 @@ static void idetape_remove_stage_head(struct ata_device *drive)
static int idetape_end_request(struct ata_device *drive, struct request *rq, int uptodate)
{
idetape_tape_t *tape = drive->driver_data;
- unsigned long flags;
+ unsigned long flags, flags2;
int error;
int remove_stage = 0;
#if ONSTREAM_DEBUG
@@ -1865,10 +1709,15 @@ static int idetape_end_request(struct ata_device *drive, struct request *rq, int
}
}
+ /* FIXME: replace tape->spinlock with channel->spinlock --bzolnier */
+ spin_lock_irqsave(drive->channel->lock, flags2);
+
blkdev_dequeue_request(rq);
drive->rq = NULL;
end_that_request_last(rq);
+ spin_unlock_irqrestore(drive->channel->lock, flags2);
+
if (remove_stage)
idetape_remove_stage_head(drive);
if (tape->active_data_request == NULL)
@@ -1887,7 +1736,7 @@ static void idetape_request_sense_callback(struct ata_device *drive, struct requ
printk (KERN_INFO "ide-tape: Reached idetape_request_sense_callback\n");
#endif
if (!tape->pc->error) {
- idetape_analyze_error (drive, (idetape_request_sense_result_t *) tape->pc->buffer);
+ idetape_analyze_error (drive, (atapi_request_sense_result_t *) tape->pc->buffer);
idetape_end_request(drive, rq, 1);
} else {
printk (KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n");
@@ -1941,7 +1790,7 @@ static void idetape_retry_pc(struct ata_device *drive)
idetape_tape_t *tape = drive->driver_data;
struct atapi_packet_command *pc;
struct request *rq;
- idetape_error_reg_t error;
+ atapi_error_reg_t error;
error.all = IN_BYTE (IDE_ERROR_REG);
pc = idetape_next_pc_storage (drive);
@@ -1978,12 +1827,10 @@ static void idetape_postpone_request(struct ata_device *drive, struct request *r
*/
static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
idetape_tape_t *tape = drive->driver_data;
- idetape_status_reg_t status;
- idetape_bcount_reg_t bcount;
- idetape_ireason_reg_t ireason;
+ atapi_status_reg_t status;
+ atapi_bcount_reg_t bcount;
+ atapi_ireason_reg_t ireason;
struct atapi_packet_command *pc = tape->pc;
unsigned int temp;
@@ -2052,14 +1899,14 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
#endif
if (pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
printk (KERN_ERR "ide-tape: I/O error in request sense command\n");
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 1)
printk(KERN_INFO "ide-tape: [cmd %x]: check condition\n", pc->c[0]);
#endif
idetape_retry_pc(drive); /* Retry operation */
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
pc->error = 0;
if (!tape->onstream && test_bit (PC_WAIT_FOR_DSC, &pc->flags) && !status.b.dsc) { /* Media access command */
@@ -2068,26 +1915,20 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
idetape_postpone_request(drive, rq); /* Allow ide.c to handle other requests */
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
if (tape->failed_pc == pc)
tape->failed_pc = NULL;
pc->callback(drive, rq); /* Command finished - Call the callback function */
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
#ifdef CONFIG_BLK_DEV_IDEDMA
if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
printk (KERN_ERR "ide-tape: The tape wants to issue more interrupts in DMA mode\n");
printk (KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
udma_enable(drive, 0, 1);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
#endif
@@ -2096,17 +1937,15 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
ireason.all = IN_BYTE (IDE_IREASON_REG);
if (ireason.b.cod) {
- spin_unlock_irqrestore(ch->lock, flags);
-
printk (KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n");
- return ide_stopped;
+
+ return ATA_OP_FINISHED;
}
if (ireason.b.io == test_bit (PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */
- spin_unlock_irqrestore(ch->lock, flags);
-
printk (KERN_ERR "ide-tape: We wanted to %s, ", ireason.b.io ? "Write":"Read");
printk (KERN_ERR "ide-tape: but the tape wants us to %s !\n",ireason.b.io ? "Read":"Write");
- return ide_stopped;
+
+ return ATA_OP_FINISHED;
}
if (!test_bit (PC_WRITING, &pc->flags)) { /* Reading - Check that we have enough space */
temp = pc->actually_transferred + bcount.all;
@@ -2115,9 +1954,8 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
atapi_discard_data (drive, bcount.all);
ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2)
@@ -2143,9 +1981,8 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all);
#endif
ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* And set the interrupt handler again */
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
/*
@@ -2192,46 +2029,41 @@ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request
*/
static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
idetape_tape_t *tape = drive->driver_data;
struct atapi_packet_command *pc = tape->pc;
- idetape_ireason_reg_t ireason;
+ atapi_ireason_reg_t ireason;
int retries = 100;
- ide_startstop_t startstop;
int ret;
- /* FIXME: Move this lock upwards.
- */
- spin_lock_irqsave(ch->lock, flags);
- if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
- WAIT_READY, rq, &startstop)) {
+ ret = ata_status_poll(drive, DRQ_STAT, BUSY_STAT, WAIT_READY, rq);
+ if (ret != ATA_OP_READY) {
printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
- ret = startstop;
- } else {
- ireason.all = IN_BYTE (IDE_IREASON_REG);
- while (retries-- && (!ireason.b.cod || ireason.b.io)) {
- printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n");
- udelay(100);
- ireason.all = IN_BYTE(IDE_IREASON_REG);
- if (retries == 0) {
- printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, ignoring\n");
- ireason.b.cod = 1;
- ireason.b.io = 0;
- }
- }
- if (!ireason.b.cod || ireason.b.io) {
- printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
- ret = ide_stopped;
- } else {
- tape->cmd_start_time = jiffies;
- ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */
- atapi_write(drive,pc->c,12); /* Send the actual packet */
- ret = ide_started;
+ return ret;
+ }
+
+ ireason.all = IN_BYTE (IDE_IREASON_REG);
+
+ while (retries-- && (!ireason.b.cod || ireason.b.io)) {
+ printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, retrying\n");
+ udelay(100);
+ ireason.all = IN_BYTE(IDE_IREASON_REG);
+ if (retries == 0) {
+ printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing a packet command, ignoring\n");
+ ireason.b.cod = 1;
+ ireason.b.io = 0;
}
}
- spin_unlock_irqrestore(ch->lock, flags);
+
+ if (!ireason.b.cod || ireason.b.io) {
+ printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
+ ret = ATA_OP_FINISHED;
+ } else {
+ tape->cmd_start_time = jiffies;
+ ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* Set the interrupt routine */
+ atapi_write(drive,pc->c,12); /* Send the actual packet */
+ ret = ATA_OP_CONTINUES;
+ }
return ret;
}
@@ -2240,7 +2072,7 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive,
struct request *rq, struct atapi_packet_command *pc)
{
idetape_tape_t *tape = drive->driver_data;
- idetape_bcount_reg_t bcount;
+ atapi_bcount_reg_t bcount;
int dma_ok = 0;
#if IDETAPE_DEBUG_BUGS
@@ -2272,7 +2104,7 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive,
}
tape->failed_pc = NULL;
pc->callback(drive, rq);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2)
@@ -2305,19 +2137,10 @@ static ide_startstop_t idetape_issue_packet_command(struct ata_device *drive,
}
#endif
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
-
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
} else {
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
return idetape_transfer_pc(drive, rq);
@@ -2451,7 +2274,7 @@ static void idetape_media_access_finished(struct ata_device *drive, struct reque
{
idetape_tape_t *tape = drive->driver_data;
struct atapi_packet_command *pc = tape->pc;
- idetape_status_reg_t status;
+ atapi_status_reg_t status;
if (tape->onstream)
printk(KERN_INFO "ide-tape: bug: onstream, media_access_finished\n");
@@ -2605,12 +2428,10 @@ static void idetape_create_write_cmd(idetape_tape_t *tape,
*/
static ide_startstop_t idetape_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
- struct ata_channel *ch = drive->channel;
idetape_tape_t *tape = drive->driver_data;
struct atapi_packet_command *pc;
struct request *postponed_rq = tape->postponed_rq;
- idetape_status_reg_t status;
- int ret;
+ atapi_status_reg_t status;
#if IDETAPE_DEBUG_LOG
/* if (tape->debug_level >= 5)
@@ -2625,32 +2446,24 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque
*/
printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request queue (%ld)\n", drive->name, rq->flags);
__ata_end_request(drive, rq, 0, 0); /* Let the common code handle it */
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/*
* Retry a failed packet command
*/
if (tape->failed_pc != NULL && tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
- int ret;
-
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
- ret = idetape_issue_packet_command(drive, rq, tape->failed_pc);
- spin_lock_irq(ch->lock);
- return ret;
+ return idetape_issue_packet_command(drive, rq, tape->failed_pc);
}
#if IDETAPE_DEBUG_BUGS
if (postponed_rq != NULL)
if (rq != postponed_rq) {
printk (KERN_ERR "ide-tape: ide-tape.c bug - Two DSC requests were queued\n");
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
+
idetape_end_request(drive, rq, 0);
- spin_lock_irq(ch->lock);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
#endif
@@ -2690,7 +2503,7 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque
idetape_queue_onstream_buffer_fill(drive);
if (jiffies > tape->insert_time)
tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
if (jiffies > tape->insert_time)
tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time);
@@ -2726,20 +2539,16 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque
tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT;
} else if ((signed long) (jiffies - tape->dsc_timeout) > 0) {
printk (KERN_ERR "ide-tape: %s: DSC timeout\n", tape->name);
- if (rq->flags == IDETAPE_PC_RQ2) {
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
+
+ if (rq->flags == IDETAPE_PC_RQ2)
idetape_media_access_finished(drive, rq);
- spin_lock_irq(ch->lock);
- return ide_stopped;
- } else {
- return ide_stopped;
- }
+
+ return ATA_OP_FINISHED;
} else if (jiffies - tape->dsc_polling_start > IDETAPE_DSC_MA_THRESHOLD)
tape->dsc_polling_frequency = IDETAPE_DSC_MA_SLOW;
idetape_postpone_request(drive, rq);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
switch (rq->flags) {
case IDETAPE_READ_RQ:
@@ -2783,7 +2592,7 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque
case IDETAPE_ABORTED_WRITE_RQ:
rq->flags = IDETAPE_WRITE_RQ;
idetape_end_request(drive, rq, IDETAPE_ERROR_EOD);
- return ide_stopped;
+ return ATA_OP_FINISHED;
case IDETAPE_ABORTED_READ_RQ:
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2)
@@ -2791,32 +2600,25 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque
#endif
rq->flags = IDETAPE_READ_RQ;
idetape_end_request(drive, rq, IDETAPE_ERROR_EOD);
- return ide_stopped;
+ return ATA_OP_FINISHED;
case IDETAPE_PC_RQ1:
/* FIXME: --mdcki */
pc = (struct atapi_packet_command *) rq->buffer;
rq->flags = IDETAPE_PC_RQ2;
break;
case IDETAPE_PC_RQ2:
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
idetape_media_access_finished(drive, rq);
- spin_lock_irq(ch->lock);
- return ide_stopped;
+
+ return ATA_OP_FINISHED;
default:
printk (KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n");
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
+
idetape_end_request(drive, rq, 0);
- spin_lock_irq(ch->lock);
- return ide_stopped;
+
+ return ATA_OP_FINISHED;
}
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
- ret = idetape_issue_packet_command(drive, rq, pc);
- spin_lock_irq(ch->lock);
- return ret;
+ return idetape_issue_packet_command(drive, rq, pc);
}
/*
@@ -5572,7 +5374,7 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp)
*/
static int idetape_identify_device(struct ata_device *drive,struct hd_driveid *id)
{
- struct idetape_id_gcw gcw;
+ struct atapi_id_gcw gcw;
#if IDETAPE_DEBUG_INFO
unsigned short mask,i;
#endif /* IDETAPE_DEBUG_INFO */
@@ -5791,14 +5593,14 @@ static void idetape_get_inquiry_results(struct ata_device *drive)
char *r;
idetape_tape_t *tape = drive->driver_data;
struct atapi_packet_command pc;
- idetape_inquiry_result_t *inquiry;
+ atapi_inquiry_result_t *inquiry;
idetape_create_inquiry_cmd(&pc);
if (idetape_queue_pc_tail (drive, &pc)) {
printk (KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", tape->name);
return;
}
- inquiry = (idetape_inquiry_result_t *) pc.buffer;
+ inquiry = (atapi_inquiry_result_t *) pc.buffer;
memcpy(tape->vendor_id, inquiry->vendor_id, 8);
memcpy(tape->product_id, inquiry->product_id, 16);
memcpy(tape->firmware_revision, inquiry->revision_level, 4);
@@ -5985,7 +5787,7 @@ static void idetape_setup(struct ata_device *drive, idetape_tape_t *tape, int mi
unsigned long t1, tmid, tn;
unsigned long t;
int speed;
- struct idetape_id_gcw gcw;
+ struct atapi_id_gcw gcw;
int stage_size;
struct sysinfo si;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index fb86527c56d8..3d6bc592766e 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -197,13 +197,14 @@ int drive_is_ready(struct ata_device *drive)
int ide_do_drive_cmd(struct ata_device *drive, struct request *rq, ide_action_t action)
{
unsigned long flags;
- unsigned int major = drive->channel->major;
+ struct ata_channel *ch = drive->channel;
+ unsigned int major = ch->major;
request_queue_t *q = &drive->queue;
struct list_head *queue_head = &q->queue_head;
DECLARE_COMPLETION(wait);
#ifdef CONFIG_BLK_DEV_PDC4030
- if (drive->channel->chipset == ide_pdc4030 && rq->buffer != NULL)
+ if (ch->chipset == ide_pdc4030 && rq->buffer)
return -ENOSYS; /* special drive cmds not supported */
#endif
rq->errors = 0;
@@ -212,22 +213,18 @@ int ide_do_drive_cmd(struct ata_device *drive, struct request *rq, ide_action_t
if (action == ide_wait)
rq->waiting = &wait;
- spin_lock_irqsave(drive->channel->lock, flags);
+ spin_lock_irqsave(ch->lock, flags);
- if (blk_queue_empty(&drive->queue) || action == ide_preempt) {
- if (action == ide_preempt)
- drive->rq = NULL;
- } else {
- if (action == ide_wait)
- queue_head = queue_head->prev;
- else
- queue_head = queue_head->next;
- }
- q->elevator.elevator_add_req_fn(q, rq, queue_head);
+ if (action == ide_preempt)
+ drive->rq = NULL;
+ else if (!blk_queue_empty(&drive->queue))
+ queue_head = queue_head->prev; /* ide_end and ide_wait */
+
+ __elv_add_request(q, rq, queue_head);
do_ide_request(q);
- spin_unlock_irqrestore(drive->channel->lock, flags);
+ spin_unlock_irqrestore(ch->lock, flags);
if (action == ide_wait) {
wait_for_completion(&wait); /* wait for it to be serviced */
@@ -235,23 +232,20 @@ int ide_do_drive_cmd(struct ata_device *drive, struct request *rq, ide_action_t
}
return 0;
-
}
/*
* Invoked on completion of a special REQ_SPECIAL command.
*/
-ide_startstop_t ata_special_intr(struct ata_device *drive, struct
+static ide_startstop_t special_intr(struct ata_device *drive, struct
request *rq) {
-
- struct ata_taskfile *ar = rq->special;
- ide_startstop_t ret = ide_stopped;
unsigned long flags;
+ struct ata_channel *ch =drive->channel;
+ struct ata_taskfile *ar = rq->special;
+ ide_startstop_t ret = ATA_OP_FINISHED;
- ide__sti(); /* local CPU only */
-
- spin_lock_irqsave(drive->channel->lock, flags);
+ ide__sti();
if (rq->buffer && ar->taskfile.sector_number) {
if (!ata_status(drive, 0, DRQ_STAT) && ar->taskfile.sector_number) {
@@ -283,24 +277,27 @@ ide_startstop_t ata_special_intr(struct ata_device *drive, struct
ata_in_regfile(drive, &ar->hobfile);
}
+ spin_lock_irqsave(ch->lock, flags);
+
blkdev_dequeue_request(rq);
drive->rq = NULL;
end_that_request_last(rq);
- spin_unlock_irqrestore(drive->channel->lock, flags);
+ spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
-int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar)
+int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar, char *buf)
{
struct request req;
ar->command_type = IDE_DRIVE_TASK_NO_DATA;
- ar->XXX_handler = ata_special_intr;
+ ar->XXX_handler = special_intr;
memset(&req, 0, sizeof(req));
req.flags = REQ_SPECIAL;
+ req.buffer = buf;
req.special = ar;
return ide_do_drive_cmd(drive, &req, ide_wait);
@@ -310,5 +307,4 @@ EXPORT_SYMBOL(drive_is_ready);
EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(ata_read);
EXPORT_SYMBOL(ata_write);
-EXPORT_SYMBOL(ata_special_intr);
EXPORT_SYMBOL(ide_raw_taskfile);
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index c8eb1e76a50a..d1e6c8030f07 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -106,15 +106,14 @@ int drive_is_flashcard(struct ata_device *drive)
return 0;
}
-/*
- * Not locking variabt of the end_request method.
- *
- * Channel lock should be held.
- */
int __ata_end_request(struct ata_device *drive, struct request *rq, int uptodate, unsigned int nr_secs)
{
+ unsigned long flags;
+ struct ata_channel *ch = drive->channel;
int ret = 1;
+ spin_lock_irqsave(ch->lock, flags);
+
BUG_ON(!(rq->flags & REQ_STARTED));
/* FIXME: Make this "small" hack to eliminate locking from
@@ -143,22 +142,7 @@ int __ata_end_request(struct ata_device *drive, struct request *rq, int uptodate
ret = 0;
}
-
- return ret;
-}
-
-/*
- * This is the default end request function as well
- */
-int ata_end_request(struct ata_device *drive, struct request *rq, int uptodate)
-{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
- int ret;
-
- spin_lock_irqsave(ch->lock, flags);
- ret = __ata_end_request(drive, rq, uptodate, 0);
- spin_unlock_irqrestore(drive->channel->lock, flags);
+ spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
@@ -169,14 +153,16 @@ int ata_end_request(struct ata_device *drive, struct request *rq, int uptodate)
* at the appropriate code to handle the next interrupt, and a
* timer is started to prevent us from waiting forever in case
* something goes wrong (see the ide_timer_expiry() handler later on).
- *
- * Channel lock should be held.
*/
void ata_set_handler(struct ata_device *drive, ata_handler_t handler,
unsigned long timeout, ata_expiry_t expiry)
{
+ unsigned long flags;
struct ata_channel *ch = drive->channel;
+ spin_lock_irqsave(ch->lock, flags);
+
+ /* FIXME: change it later to BUG_ON(ch->handler) --bzolnier */
if (ch->handler)
printk("%s: %s: handler not null; old=%p, new=%p, from %p\n",
drive->name, __FUNCTION__, ch->handler, handler, __builtin_return_address(0));
@@ -188,48 +174,35 @@ void ata_set_handler(struct ata_device *drive, ata_handler_t handler,
add_timer(&ch->timer);
+ spin_unlock_irqrestore(ch->lock, flags);
}
static void check_crc_errors(struct ata_device *drive)
{
if (!drive->using_dma)
- return;
+ return;
/* check the DMA crc count */
if (drive->crc_count) {
udma_enable(drive, 0, 0);
if (drive->channel->speedproc) {
- u8 pio = XFER_PIO_4;
+ u8 mode = drive->current_speed;
drive->crc_count = 0;
- switch (drive->current_speed) {
- case XFER_UDMA_7: pio = XFER_UDMA_6;
- break;
- case XFER_UDMA_6: pio = XFER_UDMA_5;
- break;
- case XFER_UDMA_5: pio = XFER_UDMA_4;
- break;
- case XFER_UDMA_4: pio = XFER_UDMA_3;
- break;
- case XFER_UDMA_3: pio = XFER_UDMA_2;
- break;
- case XFER_UDMA_2: pio = XFER_UDMA_1;
- break;
- case XFER_UDMA_1: pio = XFER_UDMA_0;
- break;
+ if (mode > XFER_UDMA_0)
+ mode--;
+ else
/*
* OOPS we do not goto non Ultra DMA modes
* without iCRC's available we force
* the system to PIO and make the user
* invoke the ATA-1 ATA-2 DMA modes.
*/
- case XFER_UDMA_0:
- default:
- pio = XFER_PIO_4;
- }
- drive->channel->speedproc(drive, pio);
+ mode = XFER_PIO_4;
+
+ drive->channel->speedproc(drive, mode);
}
- if (drive->current_speed >= XFER_SW_DMA_0)
+ if (drive->current_speed >= XFER_UDMA_0)
udma_enable(drive, 1, 1);
} else
udma_enable(drive, 0, 1);
@@ -262,19 +235,17 @@ static ide_startstop_t do_reset1(struct ata_device *, int); /* needed below */
* Poll the interface for completion every 50ms during an ATAPI drive reset
* operation. If the drive has not yet responded, and we have not yet hit our
* maximum waiting time, then the timer is restarted for another 50ms.
- *
- * Channel lock should be held.
*/
static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct request *__rq)
{
struct ata_channel *ch = drive->channel;
- int ret = ide_stopped;
+ int ret = ATA_OP_FINISHED;
ata_select(drive, 10);
if (!ata_status(drive, 0, BUSY_STAT)) {
if (time_before(jiffies, ch->poll_timeout)) {
ata_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
- ret = ide_started; /* continue polling */
+ ret = ATA_OP_CONTINUES; /* continue polling */
} else {
ch->poll_timeout = 0; /* end of polling */
printk("%s: ATAPI reset timed out, status=0x%02x\n", drive->name, drive->status);
@@ -285,7 +256,7 @@ static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct req
printk("%s: ATAPI reset complete\n", drive->name);
ch->poll_timeout = 0; /* done polling */
- ret = ide_stopped;
+ ret = ATA_OP_FINISHED;
}
return ret;
@@ -295,8 +266,6 @@ static ide_startstop_t atapi_reset_pollfunc(struct ata_device *drive, struct req
* Poll the interface for completion every 50ms during an ata reset operation.
* If the drives have not yet responded, and we have not yet hit our maximum
* waiting time, then the timer is restarted for another 50ms.
- *
- * Channel lock should be held.
*/
static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *__rq)
{
@@ -306,15 +275,17 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *
if (!ata_status(drive, 0, BUSY_STAT)) {
if (time_before(jiffies, ch->poll_timeout)) {
ata_set_handler(drive, reset_pollfunc, HZ/20, NULL);
- ret = ide_started; /* continue polling */
+ ret = ATA_OP_CONTINUES; /* continue polling */
} else {
+ ch->poll_timeout = 0; /* done polling */
printk("%s: reset timed out, status=0x%02x\n", ch->name, drive->status);
++drive->failures;
- ret = ide_stopped;
+ ret = ATA_OP_FINISHED;
}
} else {
u8 stat;
+ ch->poll_timeout = 0; /* done polling */
printk("%s: reset: ", ch->name);
if ((stat = GET_ERR()) == 1) {
printk("success\n");
@@ -343,11 +314,10 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *
++drive->failures;
}
- ret = ide_stopped;
+ ret = ATA_OP_FINISHED;
}
- ch->poll_timeout = 0; /* done polling */
- return ide_stopped;
+ return ret;
}
/*
@@ -364,16 +334,14 @@ static ide_startstop_t reset_pollfunc(struct ata_device *drive, struct request *
* Equally poor, though, is the fact that this may a very long time to
* complete, (up to 30 seconds worst case). So, instead of busy-waiting here
* for it, we set a timer to poll at 50ms intervals.
- *
- * Channel lock should be held.
*/
-
static ide_startstop_t do_reset1(struct ata_device *drive, int try_atapi)
{
unsigned int unit;
unsigned long flags;
struct ata_channel *ch = drive->channel;
+ /* FIXME: --bzolnier */
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
@@ -387,7 +355,7 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int try_atapi)
ata_set_handler(drive, atapi_reset_pollfunc, HZ/20, NULL);
__restore_flags(flags); /* local CPU only */
- return ide_started;
+ return ATA_OP_CONTINUES;
}
}
@@ -400,7 +368,7 @@ static ide_startstop_t do_reset1(struct ata_device *drive, int try_atapi)
__restore_flags(flags); /* local CPU only */
- return ide_started;
+ return ATA_OP_CONTINUES;
}
static inline u32 read_24(struct ata_device *drive)
@@ -467,6 +435,7 @@ u8 ata_dump(struct ata_device *drive, struct request * rq, const char *msg)
unsigned long flags;
u8 err = 0;
+ /* FIXME: --bzolnier */
__save_flags (flags); /* local CPU only */
ide__sti(); /* local CPU only */
@@ -554,7 +523,7 @@ static int do_recalibrate(struct ata_device *drive)
{
if (drive->type != ATA_DISK)
- return ide_stopped;
+ return ATA_OP_FINISHED;
if (!IS_PDC4030_DRIVE) {
struct ata_taskfile args;
@@ -563,17 +532,15 @@ static int do_recalibrate(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.sector_count = drive->sect;
args.cmd = WIN_RESTORE;
- ide_raw_taskfile(drive, &args);
+ ide_raw_taskfile(drive, &args, NULL);
printk(KERN_INFO "%s: done!\n", drive->name);
}
- return IS_PDC4030_DRIVE ? ide_stopped : ide_started;
+ return IS_PDC4030_DRIVE ? ATA_OP_FINISHED : ATA_OP_CONTINUES;
}
/*
* Take action based on the error returned by the drive.
- *
- * FIXME: Channel lock should be held.
*/
ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const char *msg)
{
@@ -581,14 +548,16 @@ ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const ch
u8 stat = drive->status;
err = ata_dump(drive, rq, msg);
+
+ /* FIXME: at least !drive check is bogus --bzolnier */
if (!drive || !rq)
- return ide_stopped;
+ return ATA_OP_FINISHED;
/* retry only "normal" I/O: */
if (!(rq->flags & REQ_CMD)) {
rq->errors = 1;
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/* other bits are useless when BUSY */
@@ -599,7 +568,7 @@ ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const ch
/* err has different meaning on cdrom and tape */
if (err == ABRT_ERR) {
if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY)
- return ide_stopped; /* some newer drives don't support WIN_SPECIFY */
+ return ATA_OP_FINISHED; /* some newer drives don't support WIN_SPECIFY */
} else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR))
drive->crc_count++; /* UDMA crc error -- just retry the operation */
else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */
@@ -617,7 +586,6 @@ ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const ch
if (rq->errors >= ERROR_MAX) {
printk(KERN_ERR "%s: max number of retries exceeded!\n", drive->name);
- /* FIXME: make sure all end_request implementations are lock free */
if (ata_ops(drive) && ata_ops(drive)->end_request)
ata_ops(drive)->end_request(drive, rq, 0);
else
@@ -627,10 +595,11 @@ ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const ch
if ((rq->errors & ERROR_RESET) == ERROR_RESET)
return do_reset1(drive, 1);
if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+ /* FIXME: tries to acquire the channel lock -Zwane */
return do_recalibrate(drive);
}
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/*
@@ -674,8 +643,9 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r
block = 1; /* redirect MBR access to EZ-Drive partn table */
ata_select(drive, 0);
- if (ata_status_poll(drive, drive->ready_stat, BUSY_STAT | DRQ_STAT,
- WAIT_READY, rq, &ret)) {
+ ret = ata_status_poll(drive, drive->ready_stat, BUSY_STAT | DRQ_STAT,
+ WAIT_READY, rq);
+ if (ret != ATA_OP_READY) {
printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
goto kill_rq;
@@ -695,38 +665,17 @@ static ide_startstop_t start_request(struct ata_device *drive, struct request *r
ret = ata_ops(drive)->do_request(drive, rq, block);
} else {
__ata_end_request(drive, rq, 0, 0);
- ret = ide_stopped;
+ ret = ATA_OP_FINISHED;
}
return ret;
kill_rq:
- if (ata_ops(drive)) {
- if (ata_ops(drive)->end_request) {
- spin_unlock_irq(ch->lock);
- ata_ops(drive)->end_request(drive, rq, 0);
- spin_lock_irq(ch->lock);
- } else
- __ata_end_request(drive, rq, 0, 0);
- } else
+ if (ata_ops(drive) && ata_ops(drive)->end_request)
+ ata_ops(drive)->end_request(drive, rq, 0);
+ else
__ata_end_request(drive, rq, 0, 0);
- return ide_stopped;
-}
-
-ide_startstop_t restart_request(struct ata_device *drive)
-{
- struct ata_channel *ch = drive->channel;
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(ch->lock, flags);
-
- ch->handler = NULL;
- del_timer(&ch->timer);
- ret = start_request(drive, drive->rq);
- spin_unlock_irqrestore(ch->lock, flags);
-
- return ret;
+ return ATA_OP_FINISHED;
}
/*
@@ -758,7 +707,7 @@ static unsigned long longest_sleep(struct ata_channel *channel)
/* This device is sleeping and waiting to be serviced
* later than any other device we checked thus far.
*/
- if (drive->sleep && (!sleep || time_after(sleep, drive->sleep)))
+ if (drive->sleep && (!sleep || time_after(drive->sleep, sleep)))
sleep = drive->sleep;
}
@@ -784,7 +733,7 @@ static struct ata_device *choose_urgent_device(struct ata_channel *channel)
/* There are no request pending for this device.
*/
- if (list_empty(&drive->queue.queue_head))
+ if (blk_queue_empty(&drive->queue))
continue;
/* This device still wants to remain idle.
@@ -834,124 +783,119 @@ static struct ata_device *choose_urgent_device(struct ata_channel *channel)
return NULL;
}
-
/*
- * Feed commands to a drive until it barfs. Called with queue lock held and
- * busy channel.
+ * Issue a new request.
+ * Caller must have already done spin_lock_irqsave(channel->lock, ...)
*/
-static void queue_commands(struct ata_device *drive)
+static void do_request(struct ata_channel *channel)
{
- struct ata_channel *ch = drive->channel;
- ide_startstop_t startstop = -1;
+ ide_get_lock(&ide_irq_lock, ata_irq_request, channel);/* for atari only: POSSIBLY BROKEN HERE(?) */
+ __cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */
- for (;;) {
+ while (!test_and_set_bit(IDE_BUSY, channel->active)) {
+ struct ata_channel *ch;
+ struct ata_device *drive;
struct request *rq = NULL;
+ ide_startstop_t startstop;
+ int i;
- if (!test_bit(IDE_BUSY, ch->active))
- printk(KERN_ERR "%s: error: not busy while queueing!\n", drive->name);
-
- /* Abort early if we can't queue another command. for non
- * tcq, ata_can_queue is always 1 since we never get here
- * unless the drive is idle.
- */
- if (!ata_can_queue(drive)) {
- if (!ata_pending_commands(drive))
- clear_bit(IDE_BUSY, ch->active);
- break;
- }
-
- drive->sleep = 0;
+ /* this will clear IDE_BUSY, if appropriate */
+ drive = choose_urgent_device(channel);
- if (test_bit(IDE_DMA, ch->active)) {
- printk(KERN_ERR "%s: error: DMA in progress...\n", drive->name);
+ if (!drive)
break;
- }
- /* There's a small window between where the queue could be
- * replugged while we are in here when using tcq (in which
- * case the queue is probably empty anyways...), so check
- * and leave if appropriate. When not using tcq, this is
- * still a severe BUG!
+ /* Remember the last drive we where acting on.
*/
- if (blk_queue_plugged(&drive->queue)) {
- BUG_ON(!drive->using_tcq);
- break;
- }
-
- if (!(rq = elv_next_request(&drive->queue))) {
- if (!ata_pending_commands(drive))
- clear_bit(IDE_BUSY, ch->active);
- drive->rq = NULL;
- break;
- }
+ ch = drive->channel;
+ ch->drive = drive;
- /* If there are queued commands, we can't start a non-fs
- * request (really, a non-queuable command) until the
- * queue is empty.
+ /* Make sure that all drives on channels sharing the IRQ line
+ * with us won't generate IRQ's during our activity.
*/
- if (!(rq->flags & REQ_CMD) && ata_pending_commands(drive))
- break;
+ for (i = 0; i < MAX_HWIFS; ++i) {
+ struct ata_channel *tmp = &ide_hwifs[i];
+ int j;
- drive->rq = rq;
+ if (!tmp->present)
+ continue;
- ide__sti(); /* allow other IRQs while we start this request */
- startstop = start_request(drive, rq);
+ if (ch->lock != tmp->lock)
+ continue;
- /* command started, we are busy */
- if (startstop == ide_started)
- break;
+ /* Only care if there is any drive on the channel in
+ * question.
+ */
+ for (j = 0; j < MAX_DRIVES; ++j) {
+ struct ata_device * other = &tmp->drives[j];
- /* start_request() can return either ide_stopped (no command
- * was started), ide_started (command started, don't queue
- * more), or ide_released (command started, try and queue
- * more).
+ if (other->present)
+ ata_irq_enable(other, 0);
+ }
+ }
+
+ /*
+ * Feed commands to a drive until it barfs.
*/
-#if 0
- if (startstop == ide_stopped)
- set_bit(IDE_BUSY, &hwgroup->flags);
-#endif
+ do {
+ if (!test_bit(IDE_BUSY, ch->active))
+ printk(KERN_ERR "%s: error: not busy while queueing!\n", drive->name);
- }
-}
+ /* Abort early if we can't queue another command. for
+ * non tcq, ata_can_queue is always 1 since we never
+ * get here unless the drive is idle.
+ */
+ if (!ata_can_queue(drive)) {
+ if (!ata_pending_commands(drive))
+ clear_bit(IDE_BUSY, ch->active);
+ break;
+ }
-/*
- * Issue a new request.
- * Caller must have already done spin_lock_irqsave(channel->lock, ...)
- */
-static void do_request(struct ata_channel *channel)
-{
- ide_get_lock(&ide_irq_lock, ata_irq_request, channel);/* for atari only: POSSIBLY BROKEN HERE(?) */
-// __cli(); /* necessary paranoia: ensure IRQs are masked on local CPU */
+ drive->sleep = 0;
- while (!test_and_set_bit(IDE_BUSY, channel->active)) {
- struct ata_channel *ch;
- struct ata_device *drive;
+ if (test_bit(IDE_DMA, ch->active)) {
+ printk(KERN_ERR "%s: error: DMA in progress...\n", drive->name);
+ break;
+ }
- /* this will clear IDE_BUSY, if appropriate */
- drive = choose_urgent_device(channel);
+ /* There's a small window between where the queue could
+ * be replugged while we are in here when using tcq (in
+ * which case the queue is probably empty anyways...),
+ * so check and leave if appropriate. When not using
+ * tcq, this is still a severe BUG!
+ */
+ if (blk_queue_plugged(&drive->queue)) {
+ BUG_ON(!drive->using_tcq);
+ break;
+ }
- if (!drive)
- break;
+ if (!(rq = elv_next_request(&drive->queue))) {
+ if (!ata_pending_commands(drive))
+ clear_bit(IDE_BUSY, ch->active);
+ drive->rq = NULL;
+ break;
+ }
- ch = drive->channel;
+ /* If there are queued commands, we can't start a
+ * non-fs request (really, a non-queuable command)
+ * until the queue is empty.
+ */
+ if (!(rq->flags & REQ_CMD) && ata_pending_commands(drive))
+ break;
- /* Disable intrerrupts from the drive on the previous channel.
- *
- * FIXME: This should be only done if we are indeed sharing the same
- * interrupt line with it.
- *
- * FIXME: check this! It appears to act on the current channel!
- */
- if (ch != channel && channel->sharing_irq && ch->irq == channel->irq)
- ata_irq_enable(drive, 0);
+ drive->rq = rq;
- /* Remember the last drive we where acting on.
- */
- ch->drive = drive;
+ spin_unlock(ch->lock);
+ ide__sti(); /* allow other IRQs while we start this request */
+ startstop = start_request(drive, rq);
+ spin_lock_irq(ch->lock);
- queue_commands(drive);
+ /* command started, we are busy */
+ } while (startstop != ATA_OP_CONTINUES);
+ /* make sure the BUSY bit is set */
+ /* FIXME: perhaps there is some place where we miss to set it? */
+// set_bit(IDE_BUSY, ch->active);
}
-
}
void do_ide_request(request_queue_t *q)
@@ -975,7 +919,7 @@ void ide_timer_expiry(unsigned long data)
del_timer(&ch->timer);
if (!ch->drive) {
- printk(KERN_ERR "%s: IRQ handler was NULL\n", __FUNCTION__);
+ printk(KERN_ERR "%s: channel->drive was NULL\n", __FUNCTION__);
ch->handler = NULL;
} else if (!ch->handler) {
@@ -995,17 +939,20 @@ void ide_timer_expiry(unsigned long data)
/* paranoia */
if (!test_and_set_bit(IDE_BUSY, ch->active))
- printk(KERN_ERR "%s: %s: IRQ handler was not busy?!\n",
+ printk(KERN_ERR "%s: %s: channel was not busy?!\n",
drive->name, __FUNCTION__);
if (ch->expiry) {
unsigned long wait;
/* continue */
- if ((wait = ch->expiry(drive, drive->rq)) != 0) {
+ ret = ch->expiry(drive, drive->rq, &wait);
+ if (ret == ATA_OP_CONTINUES) {
/* reengage timer */
- ch->timer.expires = jiffies + wait;
- add_timer(&ch->timer);
+ if (wait) {
+ ch->timer.expires = jiffies + wait;
+ add_timer(&ch->timer);
+ }
spin_unlock_irqrestore(ch->lock, flags);
@@ -1021,14 +968,14 @@ void ide_timer_expiry(unsigned long data)
handler = ch->handler;
ch->handler = NULL;
- spin_unlock(ch->lock);
- ch = drive->channel;
+ spin_unlock(ch->lock);
#if DISABLE_IRQ_NOSYNC
disable_irq_nosync(ch->irq);
#else
disable_irq(ch->irq); /* disable_irq_nosync ?? */
#endif
+ /* FIXME: IRQs are already disabled by spin_lock_irqsave() --bzolnier */
__cli(); /* local CPU only, as if we were handling an interrupt */
if (ch->poll_timeout) {
ret = handler(drive, drive->rq);
@@ -1072,18 +1019,16 @@ void ide_timer_expiry(unsigned long data)
rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
rq->buffer = NULL;
}
- ret = ide_stopped;
+ ret = ATA_OP_FINISHED;
} else
ret = ata_error(drive, drive->rq, "irq timeout");
enable_irq(ch->irq);
-
spin_lock_irq(ch->lock);
- if (ret == ide_stopped)
+ if (ret == ATA_OP_FINISHED)
clear_bit(IDE_BUSY, ch->active);
-
/* Reenter the request handling engine */
do_request(ch);
}
@@ -1153,7 +1098,7 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs)
struct ata_channel *ch = data;
unsigned long flags;
struct ata_device *drive;
- ata_handler_t *handler = ch->handler;
+ ata_handler_t *handler;
ide_startstop_t startstop;
spin_lock_irqsave(ch->lock, flags);
@@ -1161,6 +1106,7 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs)
if (!ide_ack_intr(ch))
goto out_lock;
+ handler = ch->handler;
if (handler == NULL || ch->poll_timeout != 0) {
#if 0
printk(KERN_INFO "ide: unexpected interrupt %d %d\n", ch->unit, irq);
@@ -1214,10 +1160,11 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs)
spin_unlock(ch->lock);
if (ch->unmask)
- ide__sti(); /* local CPU only */
+ ide__sti();
/* service this interrupt, may set handler for next interrupt */
startstop = handler(drive, drive->rq);
+
spin_lock_irq(ch->lock);
/*
@@ -1227,15 +1174,14 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs)
* same irq as is currently being serviced here, and Linux
* won't allow another of the same (on any CPU) until we return.
*/
- if (startstop == ide_stopped) {
+ if (startstop == ATA_OP_FINISHED) {
if (!ch->handler) { /* paranoia */
clear_bit(IDE_BUSY, ch->active);
do_request(ch);
} else {
printk("%s: %s: huh? expected NULL handler on exit\n", drive->name, __FUNCTION__);
}
- } else if (startstop == ide_released)
- queue_commands(drive);
+ }
out_lock:
spin_unlock_irqrestore(ch->lock, flags);
@@ -1386,9 +1332,6 @@ EXPORT_SYMBOL(ata_set_handler);
EXPORT_SYMBOL(ata_dump);
EXPORT_SYMBOL(ata_error);
-/* FIXME: this is a trully bad name */
-EXPORT_SYMBOL(restart_request);
-EXPORT_SYMBOL(ata_end_request);
EXPORT_SYMBOL(__ata_end_request);
EXPORT_SYMBOL(ide_stall_queue);
diff --git a/drivers/ide/ioctl.c b/drivers/ide/ioctl.c
index 83f67300baee..1c86cbc9c177 100644
--- a/drivers/ide/ioctl.c
+++ b/drivers/ide/ioctl.c
@@ -47,7 +47,6 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg)
u8 *argbuf = vals;
int argsize = 4;
struct ata_taskfile args;
- struct request req;
/* Second phase.
*/
@@ -80,15 +79,7 @@ static int do_cmd_ioctl(struct ata_device *drive, unsigned long arg)
/* Issue ATA command and wait for completion.
*/
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
- args.XXX_handler = ata_special_intr;
-
- memset(&req, 0, sizeof(req));
- req.flags = REQ_SPECIAL;
- req.special = &args;
-
- req.buffer = argbuf + 4;
- err = ide_do_drive_cmd(drive, &req, ide_wait);
+ err = ide_raw_taskfile(drive, &args, argbuf + 4);
argbuf[0] = drive->status;
argbuf[1] = args.taskfile.feature;
@@ -131,9 +122,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
case HDIO_GET_32BIT: {
unsigned long val = drive->channel->io_32bit;
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
-
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
@@ -181,9 +169,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
case HDIO_GET_UNMASKINTR: {
unsigned long val = drive->channel->unmask;
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
-
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
@@ -211,9 +196,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
case HDIO_GET_DMA: {
unsigned long val = drive->using_dma;
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
-
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
@@ -245,9 +227,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
struct hd_geometry *loc = (struct hd_geometry *) arg;
unsigned short bios_cyl = drive->bios_cyl; /* truncate */
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
-
if (!loc || (drive->type != ATA_DISK && drive->type != ATA_FLOPPY))
return -EINVAL;
@@ -270,9 +249,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
case HDIO_GETGEO_BIG_RAW: {
struct hd_big_geometry *loc = (struct hd_big_geometry *) arg;
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
-
if (!loc || (drive->type != ATA_DISK && drive->type != ATA_FLOPPY))
return -EINVAL;
@@ -293,8 +269,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
}
case HDIO_GET_IDENTITY:
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
if (minor(inode->i_rdev) & PARTN_MASK)
return -EINVAL;
@@ -308,8 +282,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
return 0;
case HDIO_GET_NICE:
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
return put_user(drive->dsc_overlap << IDE_NICE_DSC_OVERLAP |
drive->atapi_overlap << IDE_NICE_ATAPI_OVERLAP,
@@ -332,8 +304,6 @@ int ata_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
return 0;
case HDIO_GET_BUSSTATE:
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
if (put_user(drive->channel->bus_state, (long *)arg))
return -EFAULT;
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c
index 912dc2fa56b2..1c18bae107ef 100644
--- a/drivers/ide/it8172.c
+++ b/drivers/ide/it8172.c
@@ -179,14 +179,6 @@ static int it8172_tune_chipset(struct ata_device *drive, u8 speed)
return ide_config_drive_speed(drive, speed);
}
-
-static int it8172_udma_setup(struct ata_device *drive)
-{
- u8 speed = ata_timing_mode(drive, XFER_PIO | XFER_EPIO |
- XFER_SWDMA | XFER_MWDMA | XFER_UDMA);
-
- return !it8172_tune_chipset(drive, speed);
-}
#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_IT8172_TUNING) */
@@ -216,15 +208,11 @@ static void __init ide_init_it8172(struct ata_channel *hwif)
if (!hwif->dma_base)
return;
-#ifndef CONFIG_BLK_DEV_IDEDMA
- hwif->autodma = 0;
-#else /* CONFIG_BLK_DEV_IDEDMA */
# ifdef CONFIG_IT8172_TUNING
- hwif->autodma = 1;
- hwif->dmaproc = &it8172_dmaproc;
+ hwif->modes_map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA;
+ hwif->udma_setup = udma_generic_setup;
hwif->speedproc = &it8172_tune_chipset;
# endif
-#endif
cmdBase = dev->resource[0].start;
ctrlBase = dev->resource[1].start;
diff --git a/drivers/ide/main.c b/drivers/ide/main.c
index adeaa110c934..96fb19d3f89d 100644
--- a/drivers/ide/main.c
+++ b/drivers/ide/main.c
@@ -1074,7 +1074,8 @@ int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driv
spin_unlock_irqrestore(&ide_lock, flags);
/* Default autotune or requested autotune */
if (drive->autotune != 2) {
- if (drive->channel->udma_setup) {
+ struct ata_channel *ch = drive->channel;
+ if (ch->udma_setup) {
/*
* Force DMAing for the beginning of the check. Some
@@ -1085,7 +1086,7 @@ int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driv
*/
udma_enable(drive, 0, 0);
- drive->channel->udma_setup(drive);
+ ch->udma_setup(drive, ch->modes_map);
#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
udma_tcq_enable(drive, 1);
#endif
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 486cdc07af47..0431c648b720 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -105,21 +105,21 @@ static int ns87415_udma_init(struct ata_device *drive, struct request *rq)
ns87415_prepare_drive(drive, 1); /* select DMA xfer */
if (udma_pci_init(drive, rq)) /* use standard DMA stuff */
- return ide_started;
+ return ATA_OP_CONTINUES;
ns87415_prepare_drive(drive, 0); /* DMA failed: select PIO xfer */
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
-static int ns87415_udma_setup(struct ata_device *drive)
+static int ns87415_udma_setup(struct ata_device *drive, int map)
{
if (drive->type != ATA_DISK) {
udma_enable(drive, 0, 0);
return 0;
}
- return udma_pci_setup(drive);
+ return udma_pci_setup(drive, map);
}
#endif
diff --git a/drivers/ide/pcidma.c b/drivers/ide/pcidma.c
index 2199de7eecc6..4dd11411110f 100644
--- a/drivers/ide/pcidma.c
+++ b/drivers/ide/pcidma.c
@@ -27,6 +27,8 @@
#include <linux/ide.h>
#include <linux/delay.h>
+#include "ata-timing.h"
+
#include <asm/io.h>
#include <asm/irq.h>
@@ -44,18 +46,9 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
if (!dma_stat) {
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
-
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
__ata_end_request(drive, rq, 1, rq->nr_sectors);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat);
@@ -128,7 +121,7 @@ static int build_sglist(struct ata_device *drive, struct request *rq)
/*
* 1 dma-ing, 2 error, 4 intr
*/
-static int dma_timer_expiry(struct ata_device *drive, struct request *rq)
+static ide_startstop_t dma_timer_expiry(struct ata_device *drive, struct request *rq, unsigned long *wait)
{
/* FIXME: What's that? */
u8 dma_stat = inb(drive->channel->dma_base + 2);
@@ -140,15 +133,17 @@ static int dma_timer_expiry(struct ata_device *drive, struct request *rq)
#if 0
drive->expiry = NULL; /* one free ride for now */
#endif
-
+ *wait = 0;
if (dma_stat & 2) { /* ERROR */
ata_status(drive, 0, 0);
return ata_error(drive, rq, __FUNCTION__);
}
- if (dma_stat & 1) /* DMAing */
- return WAIT_CMD;
+ if (dma_stat & 1) { /* DMAing */
+ *wait = WAIT_CMD;
+ return ATA_OP_CONTINUES;
+ }
- return 0;
+ return ATA_OP_FINISHED;
}
int ata_start_dma(struct ata_device *drive, struct request *rq)
@@ -171,10 +166,73 @@ int ata_start_dma(struct ata_device *drive, struct request *rq)
return 0;
}
+/* generic udma_setup() function for drivers having ->speedproc/tuneproc */
+int udma_generic_setup(struct ata_device *drive, int map)
+{
+ struct hd_driveid *id = drive->id;
+ struct ata_channel *ch = drive->channel;
+ int on = 0;
+ u8 mode;
+
+ if (!id || (drive->type != ATA_DISK && ch->no_atapi_autodma))
+ return 0;
+
+ if ((map & XFER_UDMA_80W) && !eighty_ninty_three(drive))
+ map &= ~XFER_UDMA_80W;
+
+ if ((id->capability & 1) && ch->autodma && ch->speedproc) {
+
+ /* Consult the list of known "bad" devices. */
+ if (udma_black_list(drive))
+ goto set_dma;
+
+ mode = ata_timing_mode(drive, map);
+
+ /* Device is UltraDMA capable. */
+ if (mode & XFER_UDMA) {
+ if((on = !ch->speedproc(drive, mode)))
+ goto set_dma;
+
+ printk(KERN_WARNING "%s: UDMA auto-tune failed.\n", drive->name);
+
+ map &= ~XFER_UDMA_ALL;
+ mode = ata_timing_mode(drive, map);
+ }
+
+ /* Device is regular DMA capable. */
+ if (mode & (XFER_SWDMA | XFER_MWDMA)) {
+ if((on = !ch->speedproc(drive, mode)))
+ goto set_dma;
+
+ printk(KERN_WARNING "%s: DMA auto-tune failed.\n", drive->name);
+ }
+
+ /* FIXME: this seems non-functional --bkz */
+ /* Consult the list of known "good" devices. */
+ if (udma_white_list(drive)) {
+
+ if (id->eide_dma_time > 150)
+ goto set_dma;
+
+ printk(KERN_INFO "%s: device is on DMA whitelist.\n", drive->name);
+// on = 1;
+ }
+
+ /* Revert to PIO. */
+ if (!on && ch->tuneproc)
+ ch->tuneproc(drive, 255);
+ }
+
+set_dma:
+ udma_enable(drive, on, !on);
+
+ return 0;
+}
+
/*
* Configure a device for DMA operation.
*/
-int udma_pci_setup(struct ata_device *drive)
+int udma_pci_setup(struct ata_device *drive, int map)
{
int config_allows_dma = 1;
struct hd_driveid *id = drive->id;
@@ -399,8 +457,6 @@ int udma_new_table(struct ata_device *drive, struct request *rq)
/*
* Teardown mappings after DMA has completed.
- *
- * Channel lock should be held.
*/
void udma_destroy_table(struct ata_channel *ch)
{
@@ -411,8 +467,6 @@ void udma_destroy_table(struct ata_channel *ch)
* Prepare the channel for a DMA startfer. Please note that only the broken
* Pacific Digital host chip needs the reques to be passed there to decide
* about addressing modes.
- *
- * Channel lock should be held.
*/
void udma_pci_start(struct ata_device *drive, struct request *rq)
{
@@ -426,9 +480,6 @@ void udma_pci_start(struct ata_device *drive, struct request *rq)
outb(inb(dma_base) | 1, dma_base); /* start DMA */
}
-/*
- * Channel lock should be held.
- */
int udma_pci_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
@@ -445,8 +496,6 @@ int udma_pci_stop(struct ata_device *drive)
/*
* FIXME: This should be attached to a channel as we can see now!
- *
- * Channel lock should be held.
*/
int udma_pci_irq_status(struct ata_device *drive)
{
@@ -533,19 +582,17 @@ dma_alloc_failure:
*
* It's exported only for host chips which use it for fallback or (too) late
* capability checking.
- *
- * Channel lock should be held.
*/
int udma_pci_init(struct ata_device *drive, struct request *rq)
{
u8 cmd;
if (ata_start_dma(drive, rq))
- return ide_stopped;
+ return ATA_OP_FINISHED;
/* No DMA transfers on ATAPI devices. */
if (drive->type != ATA_DISK)
- return ide_started;
+ return ATA_OP_CONTINUES;
if (rq_data_dir(rq) == READ)
cmd = 0x08;
@@ -560,7 +607,7 @@ int udma_pci_init(struct ata_device *drive, struct request *rq)
udma_start(drive, rq);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
EXPORT_SYMBOL(ide_dma_intr);
diff --git a/drivers/ide/pcihost.h b/drivers/ide/pcihost.h
index 5ddaafca8188..cd2101bcf252 100644
--- a/drivers/ide/pcihost.h
+++ b/drivers/ide/pcihost.h
@@ -117,7 +117,6 @@ struct ata_pci_device {
unsigned short vendor;
unsigned short device;
unsigned int (*init_chipset)(struct pci_dev *);
- unsigned int (*ata66_check)(struct ata_channel *);
void (*init_channel)(struct ata_channel *);
void (*init_dma)(struct ata_channel *, unsigned long);
ide_pci_enablebit_t enablebits[2];
diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c
index 9a50c7fb507e..df7ede3b83ce 100644
--- a/drivers/ide/pdc202xx.c
+++ b/drivers/ide/pdc202xx.c
@@ -129,29 +129,30 @@ int check_in_drive_lists(struct ata_device *drive)
return 0;
}
-static int pdc202xx_ratemask(struct ata_device *drive)
+static int __init pdc202xx_modes_map(struct ata_channel *ch)
{
- struct pci_dev *dev = drive->channel->pci_dev;
- int map = 0;
-
- if (!eighty_ninty_three(drive))
- return XFER_UDMA;
+ int map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA;
- switch(dev->device) {
+ switch(ch->pci_dev->device) {
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20269:
map |= XFER_UDMA_133;
case PCI_DEVICE_ID_PROMISE_20268R:
case PCI_DEVICE_ID_PROMISE_20268:
+ map &= ~XFER_SWDMA;
case PCI_DEVICE_ID_PROMISE_20267:
case PCI_DEVICE_ID_PROMISE_20265:
map |= XFER_UDMA_100;
case PCI_DEVICE_ID_PROMISE_20262:
map |= XFER_UDMA_66;
- case PCI_DEVICE_ID_PROMISE_20246:
- map |= XFER_UDMA;
+
+ if (!ch->udma_four) {
+ printk(KERN_WARNING "%s: 40-pin cable, speed reduced to UDMA(33) mode.\n", ch->name);
+ map &= ~XFER_UDMA_80W;
+ }
}
+
return map;
}
@@ -164,9 +165,6 @@ static int pdc202xx_tune_chipset(struct ata_device *drive, byte speed)
u8 DP;
#endif
- if (drive->dn > 3) /* FIXME: remove this --bkz */
- return -1;
-
drive_pci = 0x60 + (drive->dn << 2);
if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
@@ -372,48 +370,34 @@ static void pdc202xx_tune_drive(struct ata_device *drive, u8 pio)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-/* FIXME: split this for old & new chipsets (jumpbit) --bkz */
-static int config_chipset_for_dma(struct ata_device *drive, byte udma)
+static int pdc202xx_tx_udma_setup(struct ata_device *drive, int map)
+{
+ struct hd_driveid *id = drive->id;
+ struct ata_channel *ch = drive->channel;
+ u32 indexreg = ch->dma_base + 1;
+ u32 datareg = indexreg + 2;
+ u8 adj = (drive->dn % 2) ? 0x08 : 0x00;
+
+ if (drive->type != ATA_DISK)
+ return 0;
+
+ /* IORDY_EN & PREFETCH_EN */
+ if (id->capability & 4)
+ set_2regs(0x13, (IN_BYTE(datareg)|0x03));
+
+ return udma_generic_setup(drive, map);
+}
+
+static int pdc202xx_udma_setup(struct ata_device *drive, int map)
{
- struct hd_driveid *id = drive->id;
+ struct hd_driveid *id = drive->id;
struct ata_channel *hwif = drive->channel;
struct hd_driveid *mate_id = hwif->drives[!(drive->dn%2)].id;
- struct pci_dev *dev = hwif->pci_dev;
+ struct pci_dev *dev = hwif->pci_dev;
u32 high_16 = pci_resource_start(dev, 4);
- u32 dma_base = hwif->dma_base;
- u32 indexreg = dma_base + 1;
- u32 datareg = dma_base + 3;
- byte adj = (drive->dn%2) ? 0x08 : 0x00;
- u8 jumpbit;
u32 drive_conf;
u8 drive_pci = 0, AP, tmp, mode = -1;
u8 CLKSPD, mask = hwif->unit ? 0x08 : 0x02;
- int map;
-
- /* UDMA 3, 4, 5 and 6 */
- u8 needs_80w = (id->dma_ultra & 0x0078);
-
- switch(dev->device) {
- case PCI_DEVICE_ID_PROMISE_20267:
- case PCI_DEVICE_ID_PROMISE_20265:
- case PCI_DEVICE_ID_PROMISE_20262:
- case PCI_DEVICE_ID_PROMISE_20246:
- jumpbit = 0;
- break;
- default: /* chipsets newer then 20267 */
- jumpbit = 1;
- break;
- }
-
- /* FIXME: this check is wrong for 20246 --bkz */
- /* */
- if (needs_80w && !hwif->udma_four) {
- printk(KERN_WARNING "%s: channel requires an 80-pin cable.\n", hwif->name);
- printk(KERN_INFO "%s: reduced to UDMA(33) mode.\n", drive->name);
- }
-
- if (jumpbit)
- goto chipset_is_set;
/*
* Set the control register to use the 66Mhz system
@@ -427,7 +411,7 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma)
* FIXME: move this to pdc202xx_tuneproc()
* right now you can't downgrade from U66 to U33 --bkz
*/
- if (needs_80w) {
+ if (id->dma_ultra & 0x0078) { /* UDMA 3, 4, 5 and 6 */
CLKSPD = IN_BYTE(high_16 + PDC_CLK);
/* check cable and mate (must be at least udma3 capable) */
if (!hwif->udma_four ||
@@ -449,12 +433,11 @@ static int config_chipset_for_dma(struct ata_device *drive, byte udma)
/* FIXME: what if SYNC_ERRDY is enabled for slave
and disabled for master? --bkz */
pci_read_config_byte(dev, drive_pci, &AP);
+ /* enable SYNC_ERRDY for master and slave (if enabled for master) */
if (!(AP & SYNC_ERRDY_EN)) {
- if (drive->dn == 0 || drive->dn == 2) {
- /* enable SYNC_ERRDY for master */
+ if (!(drive->dn % 2)) {
pci_write_config_byte(dev, drive_pci, AP|SYNC_ERRDY_EN);
} else {
- /* enable SYNC_ERRDY for slave if enabled for master */
pci_read_config_byte(dev, drive_pci - 4, &tmp);
if (tmp & SYNC_ERRDY_EN)
pci_write_config_byte(dev, drive_pci, AP|SYNC_ERRDY_EN);
@@ -466,85 +449,26 @@ chipset_is_set:
if (drive->type != ATA_DISK)
return 0;
- if (jumpbit) {
- if (id->capability & 4) { /* IORDY_EN & PREFETCH_EN */
- set_2regs(0x13, (IN_BYTE(datareg)|0x03));
- }
- } else {
- pci_read_config_byte(dev, drive_pci, &AP);
- if (id->capability & 4) /* IORDY_EN */
- pci_write_config_byte(dev, drive_pci, AP|IORDY_EN);
- pci_read_config_byte(dev, drive_pci, &AP);
- if (drive->type == ATA_DISK) /* PREFETCH_EN */
- pci_write_config_byte(dev, drive_pci, AP|PREFETCH_EN);
- }
+ pci_read_config_byte(dev, drive_pci, &AP);
+ if (id->capability & 4) /* IORDY_EN */
+ pci_write_config_byte(dev, drive_pci, AP|IORDY_EN);
+ pci_read_config_byte(dev, drive_pci, &AP);
+ if (drive->type == ATA_DISK) /* PREFETCH_EN */
+ pci_write_config_byte(dev, drive_pci, AP|PREFETCH_EN);
- if (udma) {
- map = pdc202xx_ratemask(drive);
- } else {
- if (!jumpbit)
- map = XFER_SWDMA | XFER_MWDMA;
- else
- map = XFER_MWDMA;
- }
+ map = hwif->modes_map;
+
+ if (!eighty_ninty_three(drive))
+ map &= ~XFER_UDMA_80W;
mode = ata_timing_mode(drive, map);
if (mode < XFER_SW_DMA_0) {
/* restore original pci-config space */
- if (!jumpbit)
- pci_write_config_dword(dev, drive_pci, drive_conf);
+ pci_write_config_dword(dev, drive_pci, drive_conf);
return 0;
}
- return !hwif->speedproc(drive, mode);
-}
-
-static int pdc202xx_udma_setup(struct ata_device *drive)
-{
- struct hd_driveid *id = drive->id;
- struct ata_channel *hwif = drive->channel;
- int on = 0;
- int verbose = 1;
-
- if (id && (id->capability & 1) && hwif->autodma) {
- /* Consult the list of known "bad" drives */
- verbose = 0;
- if (udma_black_list(drive))
- goto no_dma_set;
- if (id->field_valid & 4) {
- if (id->dma_ultra & 0x007F) {
- /* Force if Capable UltraDMA */
- on = config_chipset_for_dma(drive, 1);
- if ((id->field_valid & 2) &&
- (!on))
- goto try_dma_modes;
- }
- } else if (id->field_valid & 2) {
-try_dma_modes:
- if ((id->dma_mword & 0x0007) ||
- (id->dma_1word & 0x0007)) {
- /* Force if Capable regular DMA modes */
- on = config_chipset_for_dma(drive, 0);
- if (!on)
- goto no_dma_set;
- }
- } else if (udma_white_list(drive)) {
- if (id->eide_dma_time > 150) {
- goto no_dma_set;
- }
- /* Consult the list of known "good" drives */
- on = config_chipset_for_dma(drive, 0);
- if (!on)
- goto no_dma_set;
- } else goto no_dma_set;
- } else if ((id->capability & 8) || (id->field_valid & 2)) {
-no_dma_set:
- pdc202xx_tune_drive(drive, 255);
- }
-
- udma_enable(drive, on, verbose);
-
- return 0;
+ return udma_generic_setup(drive, map);
}
static void pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
@@ -725,12 +649,20 @@ static void __init ide_init_pdc202xx(struct ata_channel *hwif)
case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20268R:
+ hwif->udma_four = pdc202xx_tx_ata66_check(hwif);
+
hwif->speedproc = &pdc202xx_new_tune_chipset;
hwif->resetproc = &pdc202xx_new_reset;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ if (hwif->dma_base)
+ hwif->udma_setup = pdc202xx_tx_udma_setup;
+#endif
break;
case PCI_DEVICE_ID_PROMISE_20267:
case PCI_DEVICE_ID_PROMISE_20265:
case PCI_DEVICE_ID_PROMISE_20262:
+ hwif->udma_four = pdc202xx_ata66_check(hwif);
+
hwif->resetproc = &pdc202xx_reset;
#ifdef CONFIG_BLK_DEV_IDEDMA
/* we need special functions for lba48 */
@@ -741,6 +673,10 @@ static void __init ide_init_pdc202xx(struct ata_channel *hwif)
#endif
/* FIXME: check whether 20246 works with lba48 --bkz */
case PCI_DEVICE_ID_PROMISE_20246:
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ if (hwif->dma_base)
+ hwif->udma_setup = pdc202xx_udma_setup;
+#endif
hwif->speedproc = &pdc202xx_tune_chipset;
default:
break;
@@ -748,18 +684,15 @@ static void __init ide_init_pdc202xx(struct ata_channel *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
+ hwif->modes_map = pdc202xx_modes_map(hwif);
hwif->udma_irq_lost = pdc202xx_bug;
hwif->udma_timeout = pdc202xx_bug;
- hwif->udma_setup = pdc202xx_udma_setup;
hwif->highmem = 1;
- if (!noautodma)
- hwif->autodma = 1;
} else
#endif
{
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
- hwif->autodma = 0;
}
}
@@ -770,7 +703,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20246,
init_chipset: pdc202xx_init_chipset,
- ata66_check: NULL,
init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
@@ -783,7 +715,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20262,
init_chipset: pdc202xx_init_chipset,
- ata66_check: pdc202xx_ata66_check,
init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
@@ -796,7 +727,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20265,
init_chipset: pdc202xx_init_chipset,
- ata66_check: pdc202xx_ata66_check,
init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
@@ -811,7 +741,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20267,
init_chipset: pdc202xx_init_chipset,
- ata66_check: pdc202xx_ata66_check,
init_channel: ide_init_pdc202xx,
#ifndef CONFIG_PDC202XX_FORCE
enablebits: {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
@@ -824,7 +753,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20268,
init_chipset: pdc202xx_tx_init_chipset,
- ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
@@ -837,7 +765,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20268R,
init_chipset: pdc202xx_tx_init_chipset,
- ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
@@ -846,7 +773,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20269,
init_chipset: pdc202xx_tx_init_chipset,
- ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
@@ -855,7 +781,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20275,
init_chipset: pdc202xx_tx_init_chipset,
- ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
@@ -864,7 +789,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_PROMISE,
device: PCI_DEVICE_ID_PROMISE_20276,
init_chipset: pdc202xx_tx_init_chipset,
- ata66_check: pdc202xx_tx_ata66_check,
init_channel: ide_init_pdc202xx,
bootable: OFF_BOARD,
flags: ATA_F_IRQ | ATA_F_DMA
diff --git a/drivers/ide/pdc4030.c b/drivers/ide/pdc4030.c
index b92e9c96b11c..6a4153e15cee 100644
--- a/drivers/ide/pdc4030.c
+++ b/drivers/ide/pdc4030.c
@@ -230,7 +230,7 @@ int __init setup_pdc4030(struct ata_channel *hwif)
struct ata_channel *hwif2;
struct dc_ident ident;
int i;
- ide_startstop_t startstop;
+ ide_startstop_t ret;
if (!hwif)
return 0;
@@ -250,8 +250,8 @@ int __init setup_pdc4030(struct ata_channel *hwif)
/* FIXME: Make this go away. */
spin_lock_irq(hwif->lock);
- if (ata_status_poll(drive, DATA_READY, BAD_W_STAT,
- WAIT_DRQ, NULL, &startstop)) {
+ ret = ata_status_poll(drive, DATA_READY, BAD_W_STAT, WAIT_DRQ, NULL);
+ if (ret != ATA_OP_READY) {
printk(KERN_INFO
"%s: Failed Promise read config!\n",hwif->name);
spin_unlock_irq(hwif->lock);
@@ -414,10 +414,8 @@ read_next:
rq->errors = 0;
rq->nr_sectors -= nsect;
total_remaining = rq->nr_sectors;
- if ((rq->current_nr_sectors -= nsect) <= 0) {
- /* FIXME: no queue locking above! */
- ata_end_request(drive, rq, 1);
- }
+ if ((rq->current_nr_sectors -= nsect) <= 0)
+ __ata_end_request(drive, rq, 1, 0);
/*
* Now the data has been read in, do the following:
@@ -437,27 +435,18 @@ read_next:
if (drive->status & DRQ_STAT)
goto read_again;
if (drive->status & BUSY_STAT) {
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
-
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, promise_read_intr, WAIT_CMD, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
#ifdef DEBUG_READ
printk(KERN_DEBUG "%s: promise_read: waiting for"
"interrupt\n", drive->name);
#endif
- return ide_started;
+ return ATA_OP_CONTINUES;
}
printk(KERN_ERR "%s: Eeek! promise_read_intr: sectors left "
"!DRQ !BUSY\n", drive->name);
return ata_error(drive, rq, "promise read intr");
}
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/*
@@ -470,20 +459,13 @@ read_next:
*/
static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
struct ata_channel *ch = drive->channel;
if (!ata_status(drive, 0, BUSY_STAT)) {
if (time_before(jiffies, ch->poll_timeout)) {
- /* FIXME: this locking should encompass the above
- * register file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started; /* continue polling... */
+ return ATA_OP_CONTINUES; /* continue polling... */
}
ch->poll_timeout = 0;
printk(KERN_ERR "%s: completion timeout - still busy!\n",
@@ -495,15 +477,9 @@ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struc
#ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name);
#endif
- /* FIXME: this locking should encompass the above
- * register file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
__ata_end_request(drive, rq, 1, rq->nr_sectors);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/*
@@ -563,21 +539,17 @@ int promise_multwrite(struct ata_device *drive, struct request *rq, unsigned int
*/
static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
struct ata_channel *ch = drive->channel;
- spin_lock_irqsave(ch->lock, flags);
if (inb(IDE_NSECTOR_REG) != 0) {
if (time_before(jiffies, ch->poll_timeout)) {
ata_set_handler(drive, promise_write_pollfunc, HZ/100, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started; /* continue polling... */
+ return ATA_OP_CONTINUES; /* continue polling... */
}
ch->poll_timeout = 0;
printk(KERN_ERR "%s: write timed out!\n", drive->name);
ata_status(drive, 0, 0);
- spin_unlock_irqrestore(ch->lock, flags);
return ata_error(drive, rq, "write timeout");
}
@@ -592,8 +564,8 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r
printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
drive->name, drive->status);
#endif
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+
+ return ATA_OP_CONTINUES;
}
/*
@@ -605,7 +577,6 @@ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct r
*/
static ide_startstop_t promise_do_write(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
struct ata_channel *ch = drive->channel;
#ifdef DEBUG_WRITE
@@ -613,43 +584,35 @@ static ide_startstop_t promise_do_write(struct ata_device *drive, struct request
"buffer=%p\n", drive->name, rq->sector,
rq->sector + rq->nr_sectors - 1, rq->buffer);
#endif
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
/*
* If there are more than 4 sectors to transfer, do n-4 then go into
* the polling strategy as defined above.
*/
if (rq->nr_sectors > 4) {
if (promise_multwrite(drive, rq, rq->nr_sectors - 4)) {
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_stopped;
+
+ return ATA_OP_FINISHED;
}
ch->poll_timeout = jiffies + WAIT_WORSTCASE;
ata_set_handler(drive, promise_write_pollfunc, HZ/100, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
} else {
/*
* There are 4 or fewer sectors to transfer, do them all in one go
* and wait for NOT BUSY.
*/
- if (promise_multwrite(drive, rq, rq->nr_sectors)) {
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_stopped;
- }
+ if (promise_multwrite(drive, rq, rq->nr_sectors))
+ return ATA_OP_FINISHED;
+
ch->poll_timeout = jiffies + WAIT_WORSTCASE;
ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
#ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
"status = %02x\n", drive->name, drive->status);
#endif
- return ide_started;
+ return ATA_OP_CONTINUES;
}
}
@@ -666,9 +629,9 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg
/* Check that it's a regular command. If not, bomb out early. */
if (!(rq->flags & REQ_CMD)) {
blk_dump_rq_flags(rq, "pdc4030 bad flags");
- ata_end_request(drive, rq, 0);
+ __ata_end_request(drive, rq, 0, 0);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
ata_irq_enable(drive, 1);
@@ -701,34 +664,23 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg
return promise_read_intr(drive, rq);
}
if (inb(IDE_SELECT_REG) & 0x01) {
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
-
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
#ifdef DEBUG_READ
printk(KERN_DEBUG "%s: read: waiting for "
"interrupt\n", drive->name);
#endif
ata_set_handler(drive, promise_read_intr, WAIT_CMD, NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
udelay(1);
} while (time_before(jiffies, timeout));
printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n",
drive->name);
- return ide_stopped;
+ return ATA_OP_FINISHED;
case WRITE: {
- ide_startstop_t startstop;
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
+ ide_startstop_t ret;
/*
* Strategy on write is: look for the DRQ that should have been
@@ -740,29 +692,25 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg
* completion must be polled
*/
- /* FIXME: Move this lock upwards.
- */
- spin_lock_irqsave(ch->lock, flags);
- if (ata_status_poll(drive, DATA_READY, drive->bad_wstat,
- WAIT_DRQ, rq, &startstop )) {
+ ret = ata_status_poll(drive, DATA_READY, drive->bad_wstat,
+ WAIT_DRQ, rq);
+ if (ret != ATA_OP_READY) {
printk(KERN_ERR "%s: no DRQ after issuing "
"PROMISE_WRITE\n", drive->name);
- spin_unlock_irqrestore(ch->lock, flags);
- return startstop;
+ return ret;
}
if (!drive->channel->unmask)
__cli(); /* local CPU only */
- spin_unlock_irqrestore(ch->lock, flags);
return promise_do_write(drive, rq);
}
default:
printk(KERN_ERR "pdc4030: command not READ or WRITE! Huh?\n");
- /* FIXME: This should already run under the lock. */
- ata_end_request(drive, rq, 0);
- return ide_stopped;
+
+ __ata_end_request(drive, rq, 0, 0);
+ return ATA_OP_FINISHED;
}
}
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index f347e1c3b1ef..111d451dd3e7 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -244,26 +244,18 @@ static void piix_tune_drive(struct ata_device *drive, unsigned char pio)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-
-static int piix_udma_setup(struct ata_device *drive)
+static int __init piix_modes_map(struct ata_channel *ch)
{
- short w80 = drive->channel->udma_four;
-
- short speed = ata_timing_mode(drive,
- XFER_PIO | XFER_EPIO |
- (piix_config->flags & PIIX_NODMA ? 0 : (XFER_SWDMA | XFER_MWDMA |
- (piix_config->flags & PIIX_UDMA ? XFER_UDMA : 0) |
- (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 ? XFER_UDMA_66 : 0) |
- (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 ? XFER_UDMA_100 : 0) |
- (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_133 ? XFER_UDMA_133 : 0))));
-
- piix_set_drive(drive, speed);
-
- udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0);
-
- return 0;
+ short w80 = ch->udma_four;
+ int map = XFER_EPIO |
+ (piix_config->flags & PIIX_NODMA ? 0 : (XFER_SWDMA | XFER_MWDMA |
+ (piix_config->flags & PIIX_UDMA ? XFER_UDMA : 0) |
+ (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 ? XFER_UDMA_66 : 0) |
+ (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 ? XFER_UDMA_100 : 0) |
+ (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_133 ? XFER_UDMA_133 : 0)));
+
+ return map;
}
-
#endif
/*
@@ -360,9 +352,10 @@ static void __init piix_init_channel(struct ata_channel *ch)
{
int i;
+ ch->udma_four = piix_ata66_check(ch);
+
ch->tuneproc = &piix_tune_drive;
ch->speedproc = &piix_set_drive;
- ch->autodma = 0;
ch->io_32bit = 1;
ch->unmask = 1;
for (i = 0; i < 2; i++) {
@@ -373,11 +366,8 @@ static void __init piix_init_channel(struct ata_channel *ch)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (ch->dma_base) {
ch->highmem = 1;
- ch->udma_setup = piix_udma_setup;
-# ifdef CONFIG_IDEDMA_AUTO
- if (!noautodma)
- ch->autodma = 1;
-# endif
+ ch->modes_map = piix_modes_map(ch);
+ ch->udma_setup = udma_generic_setup;
}
#endif
}
@@ -401,7 +391,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82371FB_1,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -411,7 +400,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82371SB_1,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -421,7 +409,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82371AB,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -431,7 +418,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82443MX_1,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -441,7 +427,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82372FB_1,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -451,7 +436,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82801AA_1,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -461,7 +445,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82801AB_1,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -471,7 +454,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82801BA_9,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -481,7 +463,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82801BA_8,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -491,7 +472,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82801E_9,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -501,7 +481,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82801CA_10,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -511,7 +490,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82801CA_11,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -521,7 +499,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_INTEL,
device: PCI_DEVICE_ID_INTEL_82801DB_9,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
@@ -531,7 +508,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_EFAR,
device: PCI_DEVICE_ID_EFAR_SLC90E66_1,
init_chipset: piix_init_chipset,
- ata66_check: piix_ata66_check,
init_channel: piix_init_channel,
init_dma: piix_init_dma,
enablebits: {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
diff --git a/drivers/ide/probe.c b/drivers/ide/probe.c
index ab7df11e44a7..e9a62b5d03b4 100644
--- a/drivers/ide/probe.c
+++ b/drivers/ide/probe.c
@@ -312,8 +312,7 @@ byte eighty_ninty_three(struct ata_device *drive)
int ide_config_drive_speed(struct ata_device *drive, byte speed)
{
struct ata_channel *ch = drive->channel;
- int i;
- int error = 1;
+ int ret;
#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(__CRIS__)
u8 unit = (drive->select.b.unit & 0x01);
@@ -338,33 +337,14 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed)
if (drive->quirk_list == 2)
ata_irq_enable(drive, 1);
udelay(1);
-
- /* FIXME: use ata_status_poll() --bkz */
-
- ata_busy_poll(drive, WAIT_CMD);
-
- /*
- * Allow status to settle, then read it again.
- * A few rare drives vastly violate the 400ns spec here,
- * so we'll wait up to 10usec for a "good" status
- * rather than expensively fail things immediately.
- * This fix courtesy of Matthew Faupel & Niccolo Rigacci.
- */
- for (i = 0; i < 10; i++) {
- udelay(1);
- if (ata_status(drive, DRIVE_READY, BUSY_STAT | DRQ_STAT | ERR_STAT)) {
- error = 0;
- break;
- }
- }
-
+ ret = ata_status_poll(drive, 0, BUSY_STAT, WAIT_CMD, NULL);
ata_mask(drive);
enable_irq(ch->irq);
- if (error) {
+ if (ret != ATA_OP_READY) {
ata_dump(drive, NULL, "set drive speed");
- return error;
+ return 1;
}
drive->id->dma_ultra &= ~0xFF00;
@@ -399,7 +379,7 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed)
drive->current_speed = speed;
- return error;
+ return 0;
}
static inline void do_identify(struct ata_device *drive, u8 cmd)
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index 6ae18554053f..798bc253bdce 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -103,15 +103,11 @@ static u8 svwks_revision;
static struct pci_dev *isa_dev;
-static int svwks_ratemask(struct ata_device *drive)
+static int __init svwks_modes_map(struct ata_channel *ch)
{
- struct pci_dev *dev = drive->channel->pci_dev;
- int map = 0;
+ int map = XFER_EPIO | XFER_MWDMA;
- if (!eighty_ninty_three(drive))
- return XFER_UDMA;
-
- switch(dev->device) {
+ switch(ch->pci_dev->device) {
case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
if (svwks_revision >= SVWKS_CSB5_REVISION_NEW)
map |= XFER_UDMA_100;
@@ -120,6 +116,7 @@ static int svwks_ratemask(struct ata_device *drive)
map |= XFER_UDMA;
break;
}
+
return map;
}
@@ -176,6 +173,7 @@ static int svwks_tune_chipset(struct ata_device *drive, u8 speed)
csb5_pio |= ((speed - XFER_PIO_0) << (4*drive->dn));
break;
+ /* FIXME: check SWDMA modes --bkz */
#ifdef CONFIG_BLK_DEV_IDEDMA
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
@@ -224,79 +222,13 @@ static int svwks_tune_chipset(struct ata_device *drive, u8 speed)
return ide_config_drive_speed(drive, speed);
}
+/* FIXME: pio == 255 -> ata_best_pio_mode(drive) --bkz */
static void svwks_tune_drive(struct ata_device *drive, u8 pio)
{
(void) svwks_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4));
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_chipset_for_dma(struct ata_device *drive)
-{
- int map;
- u8 mode;
-
- /* FIXME: check SWDMA modes --bkz */
- map = XFER_MWDMA | svwks_ratemask(drive);
- mode = ata_timing_mode(drive, map);
-
- return !svwks_tune_chipset(drive, mode);
-}
-
-static int svwks_udma_setup(struct ata_device *drive)
-{
- struct hd_driveid *id = drive->id;
- int on = 1;
- int verbose = 1;
-
- if (id && (id->capability & 1) && drive->channel->autodma) {
- /* Consult the list of known "bad" drives */
- if (udma_black_list(drive)) {
- on = 0;
- goto fast_ata_pio;
- }
- on = 0;
- verbose = 0;
- if (id->field_valid & 4) {
- if (id->dma_ultra & 0x003F) {
- /* Force if Capable UltraDMA */
- on = config_chipset_for_dma(drive);
- if ((id->field_valid & 2) &&
- (!on))
- goto try_dma_modes;
- }
- } else if (id->field_valid & 2) {
-try_dma_modes:
- if ((id->dma_mword & 0x0007) ||
- (id->dma_1word & 0x007)) {
- /* Force if Capable regular DMA modes */
- on = config_chipset_for_dma(drive);
- if (!on)
- goto no_dma_set;
- }
- } else if (udma_white_list(drive)) {
- if (id->eide_dma_time > 150) {
- goto no_dma_set;
- }
- /* Consult the list of known "good" drives */
- on = config_chipset_for_dma(drive);
- if (!on)
- goto no_dma_set;
- } else {
- goto fast_ata_pio;
- }
- } else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
- on = 0;
- verbose = 0;
-no_dma_set:
- svwks_tune_chipset(drive, ata_best_pio_mode(drive));
- }
-
- udma_enable(drive, on, verbose);
-
- return 0;
-}
-
static int svwks_udma_stop(struct ata_device *drive)
{
struct ata_channel *ch = drive->channel;
@@ -437,24 +369,21 @@ static void __init ide_init_svwks(struct ata_channel *hwif)
if (!hwif->irq)
hwif->irq = hwif->unit ? 15 : 14;
+ hwif->udma_four = svwks_ata66_check(hwif);
+
hwif->tuneproc = &svwks_tune_drive;
hwif->speedproc = &svwks_tune_chipset;
#ifndef CONFIG_BLK_DEV_IDEDMA
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
- hwif->autodma = 0;
#else
if (hwif->dma_base) {
-#ifdef CONFIG_IDEDMA_AUTO
- if (!noautodma)
- hwif->autodma = 1;
-#endif
+ hwif->modes_map = svwks_modes_map(hwif);
+ hwif->udma_setup = udma_generic_setup;
hwif->udma_stop = svwks_udma_stop;
- hwif->udma_setup = svwks_udma_setup;
hwif->highmem = 1;
} else {
- hwif->autodma = 0;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
}
@@ -468,7 +397,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_SERVERWORKS,
device: PCI_DEVICE_ID_SERVERWORKS_OSB4IDE,
init_chipset: svwks_init_chipset,
- ata66_check: svwks_ata66_check,
init_channel: ide_init_svwks,
bootable: ON_BOARD,
flags: ATA_F_DMA
@@ -477,7 +405,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_SERVERWORKS,
device: PCI_DEVICE_ID_SERVERWORKS_CSB5IDE,
init_chipset: svwks_init_chipset,
- ata66_check: svwks_ata66_check,
init_channel: ide_init_svwks,
bootable: ON_BOARD,
flags: ATA_F_SIMPLEX
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index 78035a09ecd2..e83fe6667b62 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -207,9 +207,9 @@ static byte cycle_time_value[][XFER_UDMA_5 - XFER_UDMA_0 + 1] = {
static struct pci_dev *host_dev = NULL;
-static int sis5513_ratemask(struct ata_device *drive)
+static int __init sis5513_modes_map(struct ata_channel *ch)
{
- int map = 0;
+ int map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA;
switch(chipset_family) {
case ATA_133: /* map |= XFER_UDMA_133; */
@@ -221,15 +221,8 @@ static int sis5513_ratemask(struct ata_device *drive)
case ATA_33:
map |= XFER_UDMA;
break;
- case ATA_16:
- case ATA_00:
- default:
- return 0;
}
- if (!eighty_ninty_three(drive))
- return XFER_UDMA;
-
return map;
}
@@ -280,9 +273,6 @@ static int config_art_rwp_pio(struct ata_device *drive, u8 pio)
drive->dn, pio, timing);
#endif
- if (drive->dn > 3) /* FIXME: remove this --bkz */
- return 1;
-
drive_pci = 0x40 + (drive->dn << 1);
/* register layout changed with newer ATA100 chips */
@@ -404,86 +394,6 @@ static void sis5513_tune_drive(struct ata_device *drive, u8 pio)
(void)config_art_rwp_pio(drive, min_t(u8, pio, 4));
}
-#ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
-{
- int map;
- u8 mode;
-
-#ifdef DEBUG
- printk("SIS5513: config_chipset_for_dma, drive %d, udma %d\n",
- drive->dn, udma);
-#endif
-
- if (udma)
- map = sis5513_ratemask(drive);
- else
- map = XFER_SWDMA | XFER_MWDMA;
-
- mode = ata_timing_mode(drive, map);
- if (mode < XFER_SW_DMA_0)
- return 0;
-
- return !sis5513_tune_chipset(drive, mode);
-}
-
-static int sis5513_udma_setup(struct ata_device *drive)
-{
- struct hd_driveid *id = drive->id;
- int on = 0;
- int verbose = 1;
-
- config_drive_art_rwp(drive);
- sis5513_tune_drive(drive, 255);
-
- if (id && (id->capability & 1) && drive->channel->autodma) {
- /* Consult the list of known "bad" drives */
- if (udma_black_list(drive)) {
- on = 0;
- goto fast_ata_pio;
- }
- on = 0;
- verbose = 0;
- if (id->field_valid & 4) {
- if (id->dma_ultra & 0x003F) {
- /* Force if Capable UltraDMA */
- on = config_chipset_for_dma(drive, 1);
- if ((id->field_valid & 2) &&
- (!on))
- goto try_dma_modes;
- }
- } else if (id->field_valid & 2) {
-try_dma_modes:
- if ((id->dma_mword & 0x0007) ||
- (id->dma_1word & 0x0007)) {
- /* Force if Capable regular DMA modes */
- on = config_chipset_for_dma(drive, 0);
- if (!on)
- goto no_dma_set;
- }
- } else if ((udma_white_list(drive)) &&
- (id->eide_dma_time > 150)) {
- /* Consult the list of known "good" drives */
- on = config_chipset_for_dma(drive, 0);
- if (!on)
- goto no_dma_set;
- } else {
- goto fast_ata_pio;
- }
- } else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
- on = 0;
- verbose = 0;
-no_dma_set:
- sis5513_tune_drive(drive, 255);
- }
-
- udma_enable(drive, on, verbose);
-
- return 0;
-}
-#endif
-
/* Chip detection and general config */
static unsigned int __init pci_init_sis5513(struct pci_dev *dev)
{
@@ -576,25 +486,19 @@ static void __init ide_init_sis5513(struct ata_channel *hwif)
hwif->irq = hwif->unit ? 15 : 14;
+ hwif->udma_four = ata66_sis5513(hwif);
+
hwif->tuneproc = &sis5513_tune_drive;
hwif->speedproc = &sis5513_tune_chipset;
- if (!(hwif->dma_base))
- return;
-
- if (host_dev) {
-#ifdef CONFIG_BLK_DEV_IDEDMA
- if (chipset_family > ATA_16) {
- hwif->autodma = noautodma ? 0 : 1;
- hwif->highmem = 1;
- hwif->udma_setup = sis5513_udma_setup;
- } else {
-#endif
- hwif->autodma = 0;
#ifdef CONFIG_BLK_DEV_IDEDMA
- }
-#endif
+ if (hwif->dma_base && host_dev && chipset_family > ATA_16) {
+ hwif->highmem = 1;
+ hwif->modes_map = sis5513_modes_map(hwif);
+ hwif->udma_setup = udma_generic_setup;
}
+#endif
+
return;
}
@@ -604,11 +508,9 @@ static struct ata_pci_device chipset __initdata = {
vendor: PCI_VENDOR_ID_SI,
device: PCI_DEVICE_ID_SI_5513,
init_chipset: pci_init_sis5513,
- ata66_check: ata66_sis5513,
init_channel: ide_init_sis5513,
enablebits: {{0x4a,0x02,0x02}, {0x4a,0x04,0x04} },
bootable: ON_BOARD,
- flags: ATA_F_NOADMA
};
int __init init_sis5513(void)
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index ba36ec61cc17..abaa3d61a8d8 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -130,7 +130,7 @@ static int config_for_dma(struct ata_device *drive)
* Check to see if the drive and
* chipset is capable of DMA mode
*/
-static int sl82c105_dma_setup(struct ata_device *drive)
+static int sl82c105_dma_setup(struct ata_device *drive, int map)
{
int on = 0;
@@ -333,7 +333,6 @@ static void __init sl82c105_init_dma(struct ata_channel *ch, unsigned long dma_b
dma_state &= ~0x60;
} else {
dma_state |= 0x60;
- ch->autodma = 1;
}
outb(dma_state, dma_base + 2);
diff --git a/drivers/ide/tcq.c b/drivers/ide/tcq.c
index 4ef3929a9c67..3f64394baf09 100644
--- a/drivers/ide/tcq.c
+++ b/drivers/ide/tcq.c
@@ -57,22 +57,23 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq);
static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request *rq)
{
- struct ata_taskfile *args = rq->special;
unsigned long flags;
+ struct ata_taskfile *args = rq->special;
+ struct ata_channel *ch = drive->channel;
ide__sti();
- spin_lock_irqsave(drive->channel->lock, flags);
+ spin_lock_irqsave(ch->lock, flags);
blkdev_dequeue_request(rq);
drive->rq = NULL;
end_that_request_last(rq);
- spin_unlock_irqrestore(drive->channel->lock, flags);
+ spin_unlock_irqrestore(ch->lock, flags);
kfree(args);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/*
@@ -116,9 +117,9 @@ static void tcq_invalidate_queue(struct ata_device *drive)
goto out;
}
- rq = blk_get_request(&drive->queue, READ, GFP_ATOMIC);
+ rq = __blk_get_request(&drive->queue, READ);
if (!rq)
- rq = blk_get_request(&drive->queue, WRITE, GFP_ATOMIC);
+ rq = __blk_get_request(&drive->queue, WRITE);
/*
* blk_queue_invalidate_tags() just added back at least one command
@@ -126,6 +127,8 @@ static void tcq_invalidate_queue(struct ata_device *drive)
*/
BUG_ON(!rq);
+ /* WIN_NOP is a special request so set it's flags ?? */
+ rq->flags = REQ_SPECIAL;
rq->special = ar;
ar->cmd = WIN_NOP;
ar->XXX_handler = tcq_nop_handler;
@@ -168,7 +171,7 @@ static void ata_tcq_irq_timeout(unsigned long data)
* if pending commands, try service before giving up
*/
if (ata_pending_commands(drive) && !ata_status(drive, 0, SERVICE_STAT))
- if (service(drive, drive->rq) == ide_started)
+ if (service(drive, drive->rq) == ATA_OP_CONTINUES)
return;
if (drive)
@@ -228,13 +231,10 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *
* and it must have reported a need for service (status has SERVICE_STAT set)
*
* Also, nIEN must be set as not to need protection against ide_dmaq_intr
- *
- * Channel lock should be held.
*/
static ide_startstop_t service(struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
- ide_startstop_t ret;
unsigned long flags;
u8 feat, stat;
int tag;
@@ -246,7 +246,7 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq)
* handler, refuse to do anything.
*/
if (test_bit(IDE_DMA, drive->channel->active))
- return ide_stopped;
+ return ATA_OP_FINISHED;
/*
* need to select the right drive first...
@@ -266,7 +266,7 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq)
ata_dump(drive, rq, "BUSY clear took too long");
tcq_invalidate_queue(drive);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
#ifdef IDE_TCQ_NIEN
@@ -280,7 +280,7 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq)
ata_dump(drive, rq, "ERR condition");
tcq_invalidate_queue(drive);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/*
@@ -289,7 +289,7 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq)
if ((feat = GET_FEAT()) & NSEC_REL) {
drive->rq = NULL;
printk("%s: release in service\n", drive->name);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
tag = feat >> 3;
@@ -302,20 +302,19 @@ static ide_startstop_t service(struct ata_device *drive, struct request *rq)
if (!rq) {
printk(KERN_ERR"%s: missing request for tag %d\n", __FUNCTION__, tag);
spin_unlock_irqrestore(ch->lock, flags);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
drive->rq = rq;
+ spin_unlock_irqrestore(ch->lock, flags);
/*
* we'll start a dma read or write, device will trigger
* interrupt to indicate end of transfer, release is not allowed
*/
TCQ_PRINTK("%s: starting command %x\n", __FUNCTION__, stat);
- ret = udma_tcq_start(drive, rq);
- spin_unlock_irqrestore(ch->lock, flags);
- return ret;
+ return udma_tcq_start(drive, rq);
}
static ide_startstop_t check_service(struct ata_device *drive, struct request *rq)
@@ -323,7 +322,7 @@ static ide_startstop_t check_service(struct ata_device *drive, struct request *r
TCQ_PRINTK("%s: %s\n", drive->name, __FUNCTION__);
if (!ata_pending_commands(drive))
- return ide_stopped;
+ return ATA_OP_FINISHED;
if (!ata_status(drive, 0, SERVICE_STAT))
return service(drive, rq);
@@ -333,13 +332,11 @@ static ide_startstop_t check_service(struct ata_device *drive, struct request *r
*/
set_irq(drive, ide_dmaq_intr);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
static ide_startstop_t dmaq_complete(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
u8 dma_stat;
/*
@@ -354,7 +351,7 @@ static ide_startstop_t dmaq_complete(struct ata_device *drive, struct request *r
ata_dump(drive, rq, __FUNCTION__);
tcq_invalidate_queue(drive);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
if (dma_stat)
@@ -362,13 +359,7 @@ static ide_startstop_t dmaq_complete(struct ata_device *drive, struct request *r
TCQ_PRINTK("%s: ending %p, tag %d\n", __FUNCTION__, rq, rq->tag);
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
__ata_end_request(drive, rq, !dma_stat, rq->nr_sectors);
- spin_unlock_irqrestore(ch->lock, flags);
/*
* we completed this command, check if we can service a new command
@@ -441,7 +432,7 @@ static int check_autopoll(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.feature = 0x01;
args.cmd = WIN_NOP;
- ide_raw_taskfile(drive, &args);
+ ide_raw_taskfile(drive, &args, NULL);
if (args.taskfile.feature & ABRT_ERR)
return 1;
@@ -469,7 +460,7 @@ static int configure_tcq(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_WCACHE;
args.cmd = WIN_SETFEATURES;
- if (ide_raw_taskfile(drive, &args)) {
+ if (ide_raw_taskfile(drive, &args, NULL)) {
printk("%s: failed to enable write cache\n", drive->name);
return 1;
}
@@ -481,7 +472,7 @@ static int configure_tcq(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_DIS_RI;
args.cmd = WIN_SETFEATURES;
- if (ide_raw_taskfile(drive, &args)) {
+ if (ide_raw_taskfile(drive, &args, NULL)) {
printk("%s: disabling release interrupt fail\n", drive->name);
return 1;
}
@@ -493,7 +484,7 @@ static int configure_tcq(struct ata_device *drive)
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_SI;
args.cmd = WIN_SETFEATURES;
- if (ide_raw_taskfile(drive, &args)) {
+ if (ide_raw_taskfile(drive, &args, NULL)) {
printk("%s: enabling service interrupt fail\n", drive->name);
return 1;
}
@@ -532,8 +523,6 @@ static int tcq_wait_dataphase(struct ata_device *drive)
/*
* Invoked from a SERVICE interrupt, command etc already known. Just need to
* start the dma engine for this tag.
- *
- * Channel lock should be held.
*/
static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq)
{
@@ -544,21 +533,19 @@ static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *
printk("queued_rw: IDE_BUSY not set\n");
if (tcq_wait_dataphase(drive))
- return ide_stopped;
+ return ATA_OP_FINISHED;
if (ata_start_dma(drive, rq))
- return ide_stopped;
+ return ATA_OP_FINISHED;
__set_irq(ch, ide_dmaq_intr);
udma_start(drive, rq);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
/*
* Start a queued command from scratch.
- *
- * Channel lock should be held.
*/
ide_startstop_t udma_tcq_init(struct ata_device *drive, struct request *rq)
{
@@ -582,7 +569,7 @@ ide_startstop_t udma_tcq_init(struct ata_device *drive, struct request *rq)
if (wait_altstat(drive, &stat, BUSY_STAT)) {
ata_dump(drive, rq, "queued start");
tcq_invalidate_queue(drive);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
#ifdef IDE_TCQ_NIEN
@@ -591,7 +578,7 @@ ide_startstop_t udma_tcq_init(struct ata_device *drive, struct request *rq)
if (stat & ERR_STAT) {
ata_dump(drive, rq, "tcq_start");
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
/*
@@ -601,14 +588,14 @@ ide_startstop_t udma_tcq_init(struct ata_device *drive, struct request *rq)
if ((feat = GET_FEAT()) & NSEC_REL) {
drive->immed_rel++;
drive->rq = NULL;
- __set_irq(drive->channel, ide_dmaq_intr);
+ set_irq(drive, ide_dmaq_intr);
TCQ_PRINTK("REL in queued_start\n");
if (!ata_status(drive, 0, SERVICE_STAT))
return service(drive, rq);
- return ide_released;
+ return ATA_OP_RELEASED;
}
TCQ_PRINTK("IMMED in queued_start\n");
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index 55edeaf0a0a7..0e6587f65152 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -209,7 +209,7 @@ static int trm290_udma_init(struct ata_device *drive, struct request *rq)
#ifdef TRM290_NO_DMA_WRITES
trm290_prepare_drive(drive, 0); /* select PIO xfer */
- return ide_stopped;
+ return ATA_OP_FINISHED;
#endif
} else {
reading = 2;
@@ -218,7 +218,7 @@ static int trm290_udma_init(struct ata_device *drive, struct request *rq)
if (!(count = udma_new_table(drive, rq))) {
trm290_prepare_drive(drive, 0); /* select PIO xfer */
- return ide_stopped; /* try PIO instead of DMA */
+ return ATA_OP_FINISHED; /* try PIO instead of DMA */
}
trm290_prepare_drive(drive, 1); /* select DMA xfer */
@@ -231,7 +231,7 @@ static int trm290_udma_init(struct ata_device *drive, struct request *rq)
outb(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
}
- return ide_started;
+ return ATA_OP_CONTINUES;
}
static int trm290_udma_irq_status(struct ata_device *drive)
@@ -239,9 +239,9 @@ static int trm290_udma_irq_status(struct ata_device *drive)
return (inw(drive->channel->dma_base + 2) == 0x00ff);
}
-static int trm290_udma_setup(struct ata_device *drive)
+static int trm290_udma_setup(struct ata_device *drive, int map)
{
- return udma_pci_setup(drive);
+ return udma_pci_setup(drive, map);
}
#endif
@@ -303,7 +303,6 @@ static void __init trm290_init_channel(struct ata_channel *hwif)
#endif
hwif->selectproc = &trm290_selectproc;
- hwif->autodma = 0; /* play it safe for now */
#if 1
{
/*
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 42663b76a042..1706d4b6f42e 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -221,22 +221,16 @@ static void via82cxxx_tune_drive(struct ata_device *drive, unsigned char pio)
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-static int via82cxxx_udma_setup(struct ata_device *drive)
+static int __init via_modes_map(struct ata_channel *ch)
{
- short w80 = drive->channel->udma_four;
-
- short speed = ata_timing_mode(drive,
- XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
- (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
- (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
- (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
- (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
-
- via_set_drive(drive, speed);
-
- udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0);
-
- return 0;
+ short w80 = ch->udma_four;
+ int map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
+ (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
+ (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
+ (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
+ (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0);
+
+ return map;
}
#endif
@@ -352,9 +346,10 @@ static void __init via82cxxx_init_channel(struct ata_channel *hwif)
{
int i;
+ hwif->udma_four = via82cxxx_ata66_check(hwif);
+
hwif->tuneproc = &via82cxxx_tune_drive;
hwif->speedproc = &via_set_drive;
- hwif->autodma = 0;
hwif->io_32bit = 1;
hwif->unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
@@ -366,11 +361,8 @@ static void __init via82cxxx_init_channel(struct ata_channel *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->highmem = 1;
- hwif->udma_setup = via82cxxx_udma_setup;
-# ifdef CONFIG_IDEDMA_AUTO
- if (!noautodma)
- hwif->autodma = 1;
-# endif
+ hwif->modes_map = via_modes_map(hwif);
+ hwif->udma_setup = udma_generic_setup;
}
#endif
}
@@ -391,23 +383,19 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_VIA,
device: PCI_DEVICE_ID_VIA_82C576_1,
init_chipset: via82cxxx_init_chipset,
- ata66_check: via82cxxx_ata66_check,
init_channel: via82cxxx_init_channel,
init_dma: via82cxxx_init_dma,
enablebits: {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
bootable: ON_BOARD,
- flags: ATA_F_NOADMA
},
{
vendor: PCI_VENDOR_ID_VIA,
device: PCI_DEVICE_ID_VIA_82C586_1,
init_chipset: via82cxxx_init_chipset,
- ata66_check: via82cxxx_ata66_check,
init_channel: via82cxxx_init_channel,
init_dma: via82cxxx_init_dma,
enablebits: {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
bootable: ON_BOARD,
- flags: ATA_F_NOADMA
},
};
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 14960822b3e6..8598f13d0ee3 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -236,22 +236,26 @@ static inline idescsi_scsi_t *idescsi_private(struct Scsi_Host *host)
static int idescsi_end_request(struct ata_device *drive, struct request *rq, int uptodate)
{
+ unsigned long flags;
struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host);
struct atapi_packet_command *pc = (struct atapi_packet_command *) rq->special;
int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
u8 *scsi_buf;
- unsigned long flags;
if (!(rq->flags & REQ_PC)) {
- ata_end_request(drive, rq, uptodate);
+ __ata_end_request(drive, rq, uptodate, 0);
return 0;
}
+ spin_lock_irqsave(drive->channel->lock, flags);
+
blkdev_dequeue_request(rq);
drive->rq = NULL;
end_that_request_last(rq);
+ spin_unlock_irqrestore(drive->channel->lock, flags);
+
if (rq->errors >= ERROR_MAX) {
pc->s.scsi_cmd->result = DID_ERROR << 16;
if (log)
@@ -273,9 +277,7 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int
}
}
host = pc->s.scsi_cmd->host;
- spin_lock_irqsave(host->host_lock, flags);
pc->s.done(pc->s.scsi_cmd);
- spin_unlock_irqrestore(host->host_lock, flags);
idescsi_free_bio(rq->bio);
kfree(pc); kfree(rq);
scsi->pc = NULL;
@@ -293,8 +295,6 @@ static inline unsigned long get_timeout(struct atapi_packet_command *pc)
*/
static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host);
u8 ireason;
@@ -322,21 +322,19 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
if (drive->status & ERR_STAT)
rq->errors++;
idescsi_end_request(drive, rq, 1);
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
bcount = IN_BYTE (IDE_BCOUNTH_REG) << 8 | IN_BYTE (IDE_BCOUNTL_REG);
ireason = IN_BYTE (IDE_IREASON_REG);
if (ireason & IDESCSI_IREASON_COD) {
printk (KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n");
- return ide_stopped;
+ return ATA_OP_FINISHED;
}
if (ireason & IDESCSI_IREASON_IO) {
temp = pc->actually_transferred + bcount;
if ( temp > pc->request_transfer) {
if (temp > pc->buffer_size) {
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n");
temp = pc->buffer_size - pc->actually_transferred;
if (temp) {
@@ -350,15 +348,10 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
pc->actually_transferred += temp;
pc->current_position += temp;
atapi_discard_data(drive,bcount - temp);
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
#ifdef DEBUG
printk (KERN_NOTICE "ide-scsi: The scsi wants to send us more data than expected - allowing transfer\n");
@@ -381,48 +374,38 @@ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request
pc->actually_transferred+=bcount; /* Update the current position */
pc->current_position+=bcount;
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
- ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); /* And set the interrupt handler again */
- spin_unlock_irqrestore(ch->lock, flags);
+ /* And set the interrupt handler again */
+ ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
- return ide_started;
+ return ATA_OP_CONTINUES;
}
static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct request *rq)
{
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
struct Scsi_Host *host = drive->driver_data;
idescsi_scsi_t *scsi = idescsi_private(host);
struct atapi_packet_command *pc = scsi->pc;
u8 ireason;
- ide_startstop_t startstop;
int ret;
- /* FIXME: Move this lock upwards.
- */
- spin_lock_irqsave(ch->lock, flags);
- if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
- WAIT_READY, rq, &startstop)) {
+ ret = ata_status_poll(drive, DRQ_STAT, BUSY_STAT,
+ WAIT_READY, rq);
+ if (ret != ATA_OP_READY) {
printk (KERN_ERR "ide-scsi: Strange, packet command initiated yet DRQ isn't asserted\n");
- ret = startstop;
+
+ return ret;
+ }
+
+ ireason = IN_BYTE(IDE_IREASON_REG);
+
+ if ((ireason & (IDESCSI_IREASON_IO | IDESCSI_IREASON_COD)) != IDESCSI_IREASON_COD) {
+ printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
+ ret = ATA_OP_FINISHED;
} else {
- ireason = IN_BYTE(IDE_IREASON_REG);
-
- if ((ireason & (IDESCSI_IREASON_IO | IDESCSI_IREASON_COD)) != IDESCSI_IREASON_COD) {
- printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
- ret = ide_stopped;
- } else {
- ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
- atapi_write(drive, scsi->pc->c, 12);
- ret = ide_started;
- }
+ ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL);
+ atapi_write(drive, scsi->pc->c, 12);
+ ret = ATA_OP_CONTINUES;
}
- spin_unlock_irqrestore(ch->lock, flags);
return ret;
}
@@ -457,19 +440,10 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request
udma_start(drive, rq);
}
if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
- unsigned long flags;
- struct ata_channel *ch = drive->channel;
-
- /* FIXME: this locking should encompass the above register
- * file access too.
- */
-
- spin_lock_irqsave(ch->lock, flags);
ata_set_handler(drive, idescsi_transfer_pc, get_timeout(pc), NULL);
- spin_unlock_irqrestore(ch->lock, flags);
- OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
- return ide_started;
+ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
+ return ATA_OP_CONTINUES;
} else {
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
return idescsi_transfer_pc(drive, rq);
@@ -481,7 +455,6 @@ static ide_startstop_t idescsi_issue_pc(struct ata_device *drive, struct request
*/
static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{
- struct ata_channel *ch = drive->channel;
int ret;
#ifdef DEBUG
@@ -496,16 +469,13 @@ static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct reque
rq->current_nr_sectors);
#endif
- /* FIXME: make this unlocking go away*/
- spin_unlock_irq(ch->lock);
if (rq->flags & REQ_PC) {
ret = idescsi_issue_pc(drive, rq, (struct atapi_packet_command *) rq->special);
} else {
blk_dump_rq_flags(rq, "ide-scsi: unsup command");
idescsi_end_request(drive, rq, 0);
- ret = ide_stopped;
+ ret = ATA_OP_FINISHED;
}
- spin_lock_irq(ch->lock);
return ret;
}
@@ -720,9 +690,7 @@ static int idescsi_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
rq->flags = REQ_PC;
rq->special = (char *) pc;
rq->bio = idescsi_dma_bio (drive, pc);
- spin_unlock_irq(cmd->host->host_lock);
- ide_do_drive_cmd (drive, rq, ide_end);
- spin_lock_irq(cmd->host->host_lock);
+ ide_do_drive_cmd(drive, rq, ide_end);
return 0;
abort:
diff --git a/include/linux/atapi.h b/include/linux/atapi.h
index 029ae2b6633a..0ac305922e3a 100644
--- a/include/linux/atapi.h
+++ b/include/linux/atapi.h
@@ -12,6 +12,9 @@
* more details.
*/
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
/*
* With each packet command, we allocate a buffer.
* This is used for several packet
@@ -79,3 +82,281 @@ extern void atapi_write_zeros(struct ata_device *, unsigned int);
extern void atapi_read(struct ata_device *, u8 *, unsigned int);
extern void atapi_write(struct ata_device *, u8 *, unsigned int);
+
+/*
+ * ATAPI Status Register.
+ */
+typedef union {
+ u8 all : 8;
+ struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 check : 1; /* Error occurred */
+ u8 idx : 1; /* Reserved */
+ u8 corr : 1; /* Correctable error occurred */
+ u8 drq : 1; /* Data is request by the device */
+ u8 dsc : 1; /* Media access command finished / Buffer availability */
+ u8 reserved5 : 1; /* Reserved */
+ u8 drdy : 1; /* Ignored for ATAPI commands (ready to accept ATA command) */
+ u8 bsy : 1; /* The device has access to the command block */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 bsy : 1;
+ u8 drdy : 1;
+ u8 reserved5 : 1;
+ u8 dsc : 1;
+ u8 drq : 1;
+ u8 corr : 1;
+ u8 idx : 1;
+ u8 check : 1;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ } b;
+} atapi_status_reg_t;
+
+/*
+ * ATAPI error register.
+ */
+typedef union {
+ u8 all : 8;
+ struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 ili : 1; /* Illegal Length Indication */
+ u8 eom : 1; /* End Of Media Detected */
+ u8 abrt : 1; /* Aborted command - As defined by ATA */
+ u8 mcr : 1; /* Media Change Requested - As defined by ATA */
+ u8 sense_key : 4; /* Sense key of the last failed packet command */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 sense_key : 4;
+ u8 mcr : 1;
+ u8 abrt : 1;
+ u8 eom : 1;
+ u8 ili : 1;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ } b;
+} atapi_error_reg_t;
+
+/* Currently unused, but please do not remove. --bkz */
+/*
+ * ATAPI Feature Register.
+ */
+typedef union {
+ u8 all : 8;
+ struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 dma : 1; /* Using DMA or PIO */
+ u8 reserved321 : 3; /* Reserved */
+ u8 reserved654 : 3; /* Reserved (Tag Type) */
+ u8 reserved7 : 1; /* Reserved */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 reserved7 : 1;
+ u8 reserved654 : 3;
+ u8 reserved321 : 3;
+ u8 dma : 1;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ } b;
+} atapi_feature_reg_t;
+
+/*
+ * ATAPI Byte Count Register.
+ */
+typedef union {
+ u16 all : 16;
+ struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 low; /* LSB */
+ u8 high; /* MSB */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 high;
+ u8 low;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ } b;
+} atapi_bcount_reg_t;
+
+/*
+ * ATAPI Interrupt Reason Register.
+ */
+typedef union {
+ u8 all : 8;
+ struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 cod : 1; /* Information transferred is command (1) or data (0) */
+ u8 io : 1; /* The device requests us to read (1) or write (0) */
+ u8 reserved : 6; /* Reserved */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 reserved : 6;
+ u8 io : 1;
+ u8 cod : 1;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ } b;
+} atapi_ireason_reg_t;
+
+/* Currently unused, but please do not remove. --bkz */
+/*
+ * ATAPI Drive Select Register.
+ */
+typedef union {
+ u8 all :8;
+ struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 sam_lun :3; /* Logical unit number */
+ u8 reserved3 :1; /* Reserved */
+ u8 drv :1; /* The responding drive will be drive 0 (0) or drive 1 (1) */
+ u8 one5 :1; /* Should be set to 1 */
+ u8 reserved6 :1; /* Reserved */
+ u8 one7 :1; /* Should be set to 1 */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 one7 :1;
+ u8 reserved6 :1;
+ u8 one5 :1;
+ u8 drv :1;
+ u8 reserved3 :1;
+ u8 sam_lun :3;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ } b;
+} atapi_drivesel_reg_t;
+
+/* Currently unused, but please do not remove. --bkz */
+/*
+ * ATAPI Device Control Register.
+ */
+typedef union {
+ u8 all : 8;
+ struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 zero0 : 1; /* Should be set to zero */
+ u8 nien : 1; /* Device interrupt is disabled (1) or enabled (0) */
+ u8 srst : 1; /* ATA software reset. ATAPI devices should use the new ATAPI srst. */
+ u8 one3 : 1; /* Should be set to 1 */
+ u8 reserved4567 : 4; /* Reserved */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 reserved4567 : 4;
+ u8 one3 : 1;
+ u8 srst : 1;
+ u8 nien : 1;
+ u8 zero0 : 1;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ } b;
+} atapi_control_reg_t;
+
+/*
+ * The following is used to format the general configuration word
+ * of the ATAPI IDENTIFY DEVICE command.
+ */
+struct atapi_id_gcw {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 packet_size : 2; /* Packet Size */
+ u8 reserved234 : 3; /* Reserved */
+ u8 drq_type : 2; /* Command packet DRQ type */
+ u8 removable : 1; /* Removable media */
+ u8 device_type : 5; /* Device type */
+ u8 reserved13 : 1; /* Reserved */
+ u8 protocol : 2; /* Protocol type */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 protocol : 2;
+ u8 reserved13 : 1;
+ u8 device_type : 5;
+ u8 removable : 1;
+ u8 drq_type : 2;
+ u8 reserved234 : 3;
+ u8 packet_size : 2;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+};
+
+/*
+ * INQUIRY packet command - Data Format.
+ */
+typedef struct {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 device_type : 5; /* Peripheral Device Type */
+ u8 reserved0_765 : 3; /* Peripheral Qualifier - Reserved */
+ u8 reserved1_6t0 : 7; /* Reserved */
+ u8 rmb : 1; /* Removable Medium Bit */
+ u8 ansi_version : 3; /* ANSI Version */
+ u8 ecma_version : 3; /* ECMA Version */
+ u8 iso_version : 2; /* ISO Version */
+ u8 response_format : 4; /* Response Data Format */
+ u8 reserved3_45 : 2; /* Reserved */
+ u8 reserved3_6 : 1; /* TrmIOP - Reserved */
+ u8 reserved3_7 : 1; /* AENC - Reserved */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 reserved0_765 : 3;
+ u8 device_type : 5;
+ u8 rmb : 1;
+ u8 reserved1_6t0 : 7;
+ u8 iso_version : 2;
+ u8 ecma_version : 3;
+ u8 ansi_version : 3;
+ u8 reserved3_7 : 1;
+ u8 reserved3_6 : 1;
+ u8 reserved3_45 : 2;
+ u8 response_format : 4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ u8 additional_length; /* Additional Length (total_length-4) */
+ u8 rsv5, rsv6, rsv7; /* Reserved */
+ u8 vendor_id[8]; /* Vendor Identification */
+ u8 product_id[16]; /* Product Identification */
+ u8 revision_level[4]; /* Revision Level */
+ u8 vendor_specific[20]; /* Vendor Specific - Optional */
+ u8 reserved56t95[40]; /* Reserved - Optional */
+ /* Additional information may be returned */
+} atapi_inquiry_result_t;
+
+/*
+ * REQUEST SENSE packet command result - Data Format.
+ */
+typedef struct atapi_request_sense {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 error_code : 7; /* Error Code (0x70 - current or 0x71 - deferred) */
+ u8 valid : 1; /* The information field conforms to standard */
+ u8 reserved1 : 8; /* Reserved (Segment Number) */
+ u8 sense_key : 4; /* Sense Key */
+ u8 reserved2_4 : 1; /* Reserved */
+ u8 ili : 1; /* Incorrect Length Indicator */
+ u8 eom : 1; /* End Of Medium */
+ u8 filemark : 1; /* Filemark */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 valid : 1;
+ u8 error_code : 7;
+ u8 reserved1 : 8;
+ u8 filemark : 1;
+ u8 eom : 1;
+ u8 ili : 1;
+ u8 reserved2_4 : 1;
+ u8 sense_key : 4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ u32 information __attribute__ ((packed));
+ u8 asl; /* Additional sense length (n-7) */
+ u32 command_specific; /* Additional command specific information */
+ u8 asc; /* Additional Sense Code */
+ u8 ascq; /* Additional Sense Code Qualifier */
+ u8 replaceable_unit_code; /* Field Replaceable Unit Code */
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 sk_specific1 : 7; /* Sense Key Specific */
+ u8 sksv : 1; /* Sense Key Specific information is valid */
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ u8 sksv : 1; /* Sense Key Specific information is valid */
+ u8 sk_specific1 : 7; /* Sense Key Specific */
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ u8 sk_specific[2]; /* Sense Key Specific */
+ u8 pad[2]; /* Padding to 20 bytes */
+} atapi_request_sense_result_t;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ec38ad1d1f7b..297cb0ba10c1 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -283,7 +283,9 @@ extern void generic_make_request(struct bio *bio);
extern inline request_queue_t *bdev_get_queue(struct block_device *bdev);
extern void blkdev_release_request(struct request *);
extern void blk_attempt_remerge(request_queue_t *, struct request *);
+extern void __blk_attempt_remerge(request_queue_t *, struct request *);
extern struct request *blk_get_request(request_queue_t *, int, int);
+extern struct request *__blk_get_request(request_queue_t *, int);
extern void blk_put_request(struct request *);
extern void blk_plug_device(request_queue_t *);
extern int blk_remove_plug(request_queue_t *);
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 98426a06e782..4076310675f8 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -372,16 +372,17 @@ struct ata_device {
* Status returned by various functions.
*/
typedef enum {
- ide_stopped, /* no drive operation was started */
- ide_started, /* a drive operation was started, and a handler was set */
- ide_released /* started and released bus */
+ ATA_OP_FINISHED, /* no drive operation was started */
+ ATA_OP_CONTINUES, /* a drive operation was started, and a handler was set */
+ ATA_OP_RELEASED, /* started and released bus */
+ ATA_OP_READY, /* indicate status poll finished fine */
} ide_startstop_t;
/*
* Interrupt and timeout handler type.
*/
typedef ide_startstop_t (ata_handler_t)(struct ata_device *, struct request *);
-typedef int (ata_expiry_t)(struct ata_device *, struct request *);
+typedef ide_startstop_t (ata_expiry_t)(struct ata_device *, struct request *, unsigned long *);
enum {
ATA_PRIMARY = 0,
@@ -406,7 +407,7 @@ struct ata_channel {
ide_startstop_t (*handler)(struct ata_device *, struct request *); /* irq handler, if active */
struct timer_list timer; /* failsafe timer */
- int (*expiry)(struct ata_device *, struct request *); /* irq handler, if active */
+ ide_startstop_t (*expiry)(struct ata_device *, struct request *, unsigned long *); /* irq handler, if active */
unsigned long poll_timeout; /* timeout value during polled operations */
struct ata_device *drive; /* last serviced drive */
@@ -456,7 +457,7 @@ struct ata_channel {
void (*atapi_read)(struct ata_device *, void *, unsigned int);
void (*atapi_write)(struct ata_device *, void *, unsigned int);
- int (*udma_setup)(struct ata_device *);
+ int (*udma_setup)(struct ata_device *, int);
void (*udma_enable)(struct ata_device *, int, int);
void (*udma_start) (struct ata_device *, struct request *);
@@ -496,7 +497,9 @@ struct ata_channel {
unsigned unmask : 1; /* flag: okay to unmask other irqs */
unsigned slow : 1; /* flag: slow data port */
unsigned io_32bit : 1; /* 0=16-bit, 1=32-bit */
+ unsigned no_atapi_autodma : 1; /* flag: use auto DMA only for disks */
unsigned char bus_state; /* power state of the IDE bus */
+ int modes_map; /* map of supported transfer modes */
};
/*
@@ -602,9 +605,7 @@ extern int noautodma;
#define DEVICE_NR(device) (minor(device) >> PARTN_BITS)
#include <linux/blk.h>
-/* Not locking and locking variant: */
extern int __ata_end_request(struct ata_device *, struct request *, int, unsigned int);
-extern int ata_end_request(struct ata_device *drive, struct request *, int);
extern void ata_set_handler(struct ata_device *drive, ata_handler_t handler,
unsigned long timeout, ata_expiry_t expiry);
@@ -626,12 +627,6 @@ int ide_xlate_1024(kdev_t, int, int, const char *);
struct ata_device *get_info_ptr(kdev_t i_rdev);
/*
- * Re-Start an operation for an IDE interface.
- * The caller should return immediately after invoking this.
- */
-ide_startstop_t restart_request(struct ata_device *);
-
-/*
* "action" parameter type for ide_do_drive_cmd() below.
*/
typedef enum {
@@ -658,31 +653,7 @@ struct ata_taskfile {
extern void ata_read(struct ata_device *, void *, unsigned int);
extern void ata_write(struct ata_device *, void *, unsigned int);
-/*
- * Special Flagged Register Validation Caller
- */
-
-/*
- * for now, taskfile requests are special :/
- */
-static inline char *ide_map_rq(struct request *rq, unsigned long *flags)
-{
- if (rq->bio)
- return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
- else
- return rq->buffer + ((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE;
-}
-
-static inline void ide_unmap_rq(struct request *rq, char *to,
- unsigned long *flags)
-{
- if (rq->bio)
- bio_kunmap_irq(to, flags);
-}
-
-extern ide_startstop_t ata_special_intr(struct ata_device *, struct request *);
-extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *);
-
+extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *, char *);
extern void ide_fix_driveid(struct hd_driveid *id);
extern int ide_config_drive_speed(struct ata_device *, byte);
extern byte eighty_ninty_three(struct ata_device *);
@@ -756,9 +727,12 @@ static inline void udma_start(struct ata_device *drive, struct request *rq)
static inline int udma_stop(struct ata_device *drive)
{
+ int ret;
+
+ ret = drive->channel->udma_stop(drive);
clear_bit(IDE_DMA, drive->channel->active);
- return drive->channel->udma_stop(drive);
+ return ret;
}
/*
@@ -766,9 +740,12 @@ static inline int udma_stop(struct ata_device *drive)
*/
static inline ide_startstop_t udma_init(struct ata_device *drive, struct request *rq)
{
- int ret = drive->channel->udma_init(drive, rq);
- if (ret == ide_started)
- set_bit(IDE_DMA, drive->channel->active);
+ int ret;
+
+ set_bit(IDE_DMA, drive->channel->active);
+ ret = drive->channel->udma_init(drive, rq);
+ if (ret != ATA_OP_CONTINUES)
+ clear_bit(IDE_DMA, drive->channel->active);
return ret;
}
@@ -797,7 +774,9 @@ extern int udma_pci_init(struct ata_device *drive, struct request *rq);
extern int udma_pci_irq_status(struct ata_device *drive);
extern void udma_pci_timeout(struct ata_device *drive);
extern void udma_pci_irq_lost(struct ata_device *);
-extern int udma_pci_setup(struct ata_device *);
+extern int udma_pci_setup(struct ata_device *, int);
+
+extern int udma_generic_setup(struct ata_device *, int);
extern int udma_new_table(struct ata_device *, struct request *);
extern void udma_destroy_table(struct ata_channel *);
@@ -830,10 +809,9 @@ extern int drive_is_ready(struct ata_device *drive);
extern void ata_select(struct ata_device *, unsigned long);
extern void ata_mask(struct ata_device *);
-extern int ata_busy_poll(struct ata_device *, unsigned long);
extern int ata_status(struct ata_device *, u8, u8);
extern int ata_status_poll( struct ata_device *, u8, u8,
- unsigned long, struct request *rq, ide_startstop_t *);
+ unsigned long, struct request *rq);
extern int ata_irq_enable(struct ata_device *, int);
extern void ata_reset(struct ata_channel *);