diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 16:57:26 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 16:57:26 -0500 |
| commit | f31c338675872875e24f124af0689131b0c72600 (patch) | |
| tree | cf12b28d52da1675ab32871abd2db455ffbfe920 | |
| parent | 0008bf54408d4c0637c24d34642f1038c299be95 (diff) | |
| parent | 61a368c216897aa3bbee35b3f2e6db76ec73fad0 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (67 commits)
ide: remove redundant DMA blacklist check from __ide_dma_on()
ide: cleanup ide_set_dma()
ide: remove redundant ->ide_dma_on call from set_using_dma()
sc1200: move DMA timings to timing tables
ide: add IDE_HFLAG_ABUSE_SET_DMA_MODE host flag
sis5513: factor out UDMA programming code
pdc202xx_new: move PIO programming code to pdcnew_set_pio_mode()
ide: make 'extra' field in struct ide_port_info u8
ide: kill duplicate code in ide_dump_{ata,atapi}_status()
ide-disk: use ide_get_lba_addr()
ide: printk fix
ide: add ide_tf_read() helper
ide: fix registers loading order in ide_dump_ata_status()
ide-disk: use do_rw_taskfile() (take 2)
ide-disk: add ide_tf_set_cmd() helper
ide-disk: extend timeout for PIO-in commands
ide: remove 'handler' field from ide_task_t (take 2)
ide: use ->data_phase to set ->handler in do_rw_taskfile()
ide: convert do_rw_taskfile() to use ->data_phase
ide: merge flagged_taskfile() into do_rw_taskfile()
...
50 files changed, 1265 insertions, 1853 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index fb06555708a8..ee01e273a537 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
| @@ -374,17 +374,6 @@ comment "PCI IDE chipsets support" | |||
| 374 | config BLK_DEV_IDEPCI | 374 | config BLK_DEV_IDEPCI |
| 375 | bool | 375 | bool |
| 376 | 376 | ||
| 377 | config IDEPCI_SHARE_IRQ | ||
| 378 | bool "Sharing PCI IDE interrupts support" | ||
| 379 | depends on BLK_DEV_IDEPCI | ||
| 380 | help | ||
| 381 | Some ATA/IDE chipsets have hardware support which allows for | ||
| 382 | sharing a single IRQ with other cards. To enable support for | ||
| 383 | this in the ATA/IDE driver, say Y here. | ||
| 384 | |||
| 385 | It is safe to say Y to this question, in most cases. | ||
| 386 | If unsure, say N. | ||
| 387 | |||
| 388 | config IDEPCI_PCIBUS_ORDER | 377 | config IDEPCI_PCIBUS_ORDER |
| 389 | def_bool BLK_DEV_IDE=y && BLK_DEV_IDEPCI | 378 | def_bool BLK_DEV_IDE=y && BLK_DEV_IDEPCI |
| 390 | 379 | ||
| @@ -707,7 +696,6 @@ config BLK_DEV_SVWKS | |||
| 707 | config BLK_DEV_SGIIOC4 | 696 | config BLK_DEV_SGIIOC4 |
| 708 | tristate "Silicon Graphics IOC4 chipset ATA/ATAPI support" | 697 | tristate "Silicon Graphics IOC4 chipset ATA/ATAPI support" |
| 709 | depends on (IA64_SGI_SN2 || IA64_GENERIC) && SGI_IOC4 | 698 | depends on (IA64_SGI_SN2 || IA64_GENERIC) && SGI_IOC4 |
| 710 | select IDEPCI_SHARE_IRQ | ||
| 711 | select BLK_DEV_IDEDMA_PCI | 699 | select BLK_DEV_IDEDMA_PCI |
| 712 | help | 700 | help |
| 713 | This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 | 701 | This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 |
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 93f71fcfc04d..673402f4a295 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c | |||
| @@ -272,8 +272,6 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) | |||
| 272 | case XFER_SW_DMA_0: | 272 | case XFER_SW_DMA_0: |
| 273 | cycle_time = 480; | 273 | cycle_time = 480; |
| 274 | break; | 274 | break; |
| 275 | default: | ||
| 276 | return; | ||
| 277 | } | 275 | } |
| 278 | 276 | ||
| 279 | /* | 277 | /* |
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index 476e0d65ed43..325e608d9e62 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c | |||
| @@ -747,8 +747,6 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 747 | strobe = ATA_DMA2_STROBE; | 747 | strobe = ATA_DMA2_STROBE; |
| 748 | hold = ATA_DMA2_HOLD; | 748 | hold = ATA_DMA2_HOLD; |
| 749 | break; | 749 | break; |
| 750 | default: | ||
| 751 | return; | ||
| 752 | } | 750 | } |
| 753 | 751 | ||
| 754 | if (speed >= XFER_UDMA_0) | 752 | if (speed >= XFER_UDMA_0) |
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 899d56536e80..e0bb0cfa7bdd 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
| @@ -383,27 +383,19 @@ static int taskfile_load_raw(ide_drive_t *drive, | |||
| 383 | gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]); | 383 | gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]); |
| 384 | 384 | ||
| 385 | memset(&args, 0, sizeof(ide_task_t)); | 385 | memset(&args, 0, sizeof(ide_task_t)); |
| 386 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | ||
| 387 | args.data_phase = TASKFILE_NO_DATA; | ||
| 388 | args.handler = &task_no_data_intr; | ||
| 389 | 386 | ||
| 390 | /* convert gtf to IDE Taskfile */ | 387 | /* convert gtf to IDE Taskfile */ |
| 391 | args.tfRegister[1] = gtf->tfa[0]; /* 0x1f1 */ | 388 | memcpy(&args.tf_array[7], >f->tfa, 7); |
| 392 | args.tfRegister[2] = gtf->tfa[1]; /* 0x1f2 */ | 389 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 393 | args.tfRegister[3] = gtf->tfa[2]; /* 0x1f3 */ | ||
| 394 | args.tfRegister[4] = gtf->tfa[3]; /* 0x1f4 */ | ||
| 395 | args.tfRegister[5] = gtf->tfa[4]; /* 0x1f5 */ | ||
| 396 | args.tfRegister[6] = gtf->tfa[5]; /* 0x1f6 */ | ||
| 397 | args.tfRegister[7] = gtf->tfa[6]; /* 0x1f7 */ | ||
| 398 | 390 | ||
| 399 | if (ide_noacpitfs) { | 391 | if (ide_noacpitfs) { |
| 400 | DEBPRINT("_GTF execution disabled\n"); | 392 | DEBPRINT("_GTF execution disabled\n"); |
| 401 | return err; | 393 | return err; |
| 402 | } | 394 | } |
| 403 | 395 | ||
| 404 | err = ide_raw_taskfile(drive, &args, NULL); | 396 | err = ide_no_data_taskfile(drive, &args); |
| 405 | if (err) | 397 | if (err) |
| 406 | printk(KERN_ERR "%s: ide_raw_taskfile failed: %u\n", | 398 | printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n", |
| 407 | __FUNCTION__, err); | 399 | __FUNCTION__, err); |
| 408 | 400 | ||
| 409 | return err; | 401 | return err; |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index c7d77f0ad892..44b033ec0ab0 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -917,19 +917,13 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, | |||
| 917 | if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY)) | 917 | if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY)) |
| 918 | return startstop; | 918 | return startstop; |
| 919 | 919 | ||
| 920 | /* FIXME: for Virtual DMA we must check harder */ | ||
| 920 | if (info->dma) | 921 | if (info->dma) |
| 921 | info->dma = !hwif->dma_setup(drive); | 922 | info->dma = !hwif->dma_setup(drive); |
| 922 | 923 | ||
| 923 | /* Set up the controller registers. */ | 924 | /* Set up the controller registers. */ |
| 924 | /* FIXME: for Virtual DMA we must check harder */ | 925 | ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL | |
| 925 | HWIF(drive)->OUTB(info->dma, IDE_FEATURE_REG); | 926 | IDE_TFLAG_NO_SELECT_MASK, xferlen, info->dma); |
| 926 | HWIF(drive)->OUTB(0, IDE_IREASON_REG); | ||
| 927 | HWIF(drive)->OUTB(0, IDE_SECTOR_REG); | ||
| 928 | |||
| 929 | HWIF(drive)->OUTB(xferlen & 0xff, IDE_BCOUNTL_REG); | ||
| 930 | HWIF(drive)->OUTB(xferlen >> 8 , IDE_BCOUNTH_REG); | ||
| 931 | if (IDE_CONTROL_REG) | ||
| 932 | HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); | ||
| 933 | 927 | ||
| 934 | if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { | 928 | if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { |
| 935 | /* waiting for CDB interrupt, not DMA yet. */ | 929 | /* waiting for CDB interrupt, not DMA yet. */ |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index b1781908e1f2..d8fdd865dea9 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
| @@ -129,6 +129,50 @@ static int lba_capacity_is_ok (struct hd_driveid *id) | |||
| 129 | return 0; /* lba_capacity value may be bad */ | 129 | return 0; /* lba_capacity value may be bad */ |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static const u8 ide_rw_cmds[] = { | ||
| 133 | WIN_MULTREAD, | ||
| 134 | WIN_MULTWRITE, | ||
| 135 | WIN_MULTREAD_EXT, | ||
| 136 | WIN_MULTWRITE_EXT, | ||
| 137 | WIN_READ, | ||
| 138 | WIN_WRITE, | ||
| 139 | WIN_READ_EXT, | ||
| 140 | WIN_WRITE_EXT, | ||
| 141 | WIN_READDMA, | ||
| 142 | WIN_WRITEDMA, | ||
| 143 | WIN_READDMA_EXT, | ||
| 144 | WIN_WRITEDMA_EXT, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static const u8 ide_data_phases[] = { | ||
| 148 | TASKFILE_MULTI_IN, | ||
| 149 | TASKFILE_MULTI_OUT, | ||
| 150 | TASKFILE_IN, | ||
| 151 | TASKFILE_OUT, | ||
| 152 | TASKFILE_IN_DMA, | ||
| 153 | TASKFILE_OUT_DMA, | ||
| 154 | }; | ||
| 155 | |||
| 156 | static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma) | ||
| 157 | { | ||
| 158 | u8 index, lba48, write; | ||
| 159 | |||
| 160 | lba48 = (task->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0; | ||
| 161 | write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0; | ||
| 162 | |||
| 163 | if (dma) | ||
| 164 | index = drive->vdma ? 4 : 8; | ||
| 165 | else | ||
| 166 | index = drive->mult_count ? 0 : 4; | ||
| 167 | |||
| 168 | task->tf.command = ide_rw_cmds[index + lba48 + write]; | ||
| 169 | |||
| 170 | if (dma) | ||
| 171 | index = 8; /* fixup index */ | ||
| 172 | |||
| 173 | task->data_phase = ide_data_phases[index / 2 + write]; | ||
| 174 | } | ||
| 175 | |||
| 132 | /* | 176 | /* |
| 133 | * __ide_do_rw_disk() issues READ and WRITE commands to a disk, | 177 | * __ide_do_rw_disk() issues READ and WRITE commands to a disk, |
| 134 | * using LBA if supported, or CHS otherwise, to address sectors. | 178 | * using LBA if supported, or CHS otherwise, to address sectors. |
| @@ -137,11 +181,11 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
| 137 | { | 181 | { |
| 138 | ide_hwif_t *hwif = HWIF(drive); | 182 | ide_hwif_t *hwif = HWIF(drive); |
| 139 | unsigned int dma = drive->using_dma; | 183 | unsigned int dma = drive->using_dma; |
| 184 | u16 nsectors = (u16)rq->nr_sectors; | ||
| 140 | u8 lba48 = (drive->addressing == 1) ? 1 : 0; | 185 | u8 lba48 = (drive->addressing == 1) ? 1 : 0; |
| 141 | task_ioreg_t command = WIN_NOP; | 186 | ide_task_t task; |
| 142 | ata_nsector_t nsectors; | 187 | struct ide_taskfile *tf = &task.tf; |
| 143 | 188 | ide_startstop_t rc; | |
| 144 | nsectors.all = (u16) rq->nr_sectors; | ||
| 145 | 189 | ||
| 146 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) { | 190 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) { |
| 147 | if (block + rq->nr_sectors > 1ULL << 28) | 191 | if (block + rq->nr_sectors > 1ULL << 28) |
| @@ -155,121 +199,76 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
| 155 | ide_map_sg(drive, rq); | 199 | ide_map_sg(drive, rq); |
| 156 | } | 200 | } |
| 157 | 201 | ||
| 158 | if (IDE_CONTROL_REG) | 202 | memset(&task, 0, sizeof(task)); |
| 159 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | 203 | task.tf_flags = IDE_TFLAG_NO_SELECT_MASK; /* FIXME? */ |
| 160 | 204 | task.tf_flags |= (IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE); | |
| 161 | /* FIXME: SELECT_MASK(drive, 0) ? */ | ||
| 162 | 205 | ||
| 163 | if (drive->select.b.lba) { | 206 | if (drive->select.b.lba) { |
| 164 | if (lba48) { | 207 | if (lba48) { |
| 165 | task_ioreg_t tasklets[10]; | ||
| 166 | |||
| 167 | pr_debug("%s: LBA=0x%012llx\n", drive->name, | 208 | pr_debug("%s: LBA=0x%012llx\n", drive->name, |
| 168 | (unsigned long long)block); | 209 | (unsigned long long)block); |
| 169 | 210 | ||
| 170 | tasklets[0] = 0; | 211 | tf->hob_nsect = (nsectors >> 8) & 0xff; |
| 171 | tasklets[1] = 0; | 212 | tf->hob_lbal = (u8)(block >> 24); |
| 172 | tasklets[2] = nsectors.b.low; | 213 | if (sizeof(block) != 4) { |
| 173 | tasklets[3] = nsectors.b.high; | 214 | tf->hob_lbam = (u8)((u64)block >> 32); |
| 174 | tasklets[4] = (task_ioreg_t) block; | 215 | tf->hob_lbah = (u8)((u64)block >> 40); |
| 175 | tasklets[5] = (task_ioreg_t) (block>>8); | ||
| 176 | tasklets[6] = (task_ioreg_t) (block>>16); | ||
| 177 | tasklets[7] = (task_ioreg_t) (block>>24); | ||
| 178 | if (sizeof(block) == 4) { | ||
| 179 | tasklets[8] = (task_ioreg_t) 0; | ||
| 180 | tasklets[9] = (task_ioreg_t) 0; | ||
| 181 | } else { | ||
| 182 | tasklets[8] = (task_ioreg_t)((u64)block >> 32); | ||
| 183 | tasklets[9] = (task_ioreg_t)((u64)block >> 40); | ||
| 184 | } | 216 | } |
| 217 | |||
| 218 | tf->nsect = nsectors & 0xff; | ||
| 219 | tf->lbal = (u8) block; | ||
| 220 | tf->lbam = (u8)(block >> 8); | ||
| 221 | tf->lbah = (u8)(block >> 16); | ||
| 185 | #ifdef DEBUG | 222 | #ifdef DEBUG |
| 186 | printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n", | 223 | printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n", |
| 187 | drive->name, tasklets[3], tasklets[2], | 224 | drive->name, tf->hob_nsect, tf->nsect, |
| 188 | tasklets[9], tasklets[8], tasklets[7], | 225 | tf->hob_lbah, tf->hob_lbam, tf->hob_lbal, |
| 189 | tasklets[6], tasklets[5], tasklets[4]); | 226 | tf->lbah, tf->lbam, tf->lbal); |
| 190 | #endif | 227 | #endif |
| 191 | hwif->OUTB(tasklets[1], IDE_FEATURE_REG); | 228 | task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB); |
| 192 | hwif->OUTB(tasklets[3], IDE_NSECTOR_REG); | ||
| 193 | hwif->OUTB(tasklets[7], IDE_SECTOR_REG); | ||
| 194 | hwif->OUTB(tasklets[8], IDE_LCYL_REG); | ||
| 195 | hwif->OUTB(tasklets[9], IDE_HCYL_REG); | ||
| 196 | |||
| 197 | hwif->OUTB(tasklets[0], IDE_FEATURE_REG); | ||
| 198 | hwif->OUTB(tasklets[2], IDE_NSECTOR_REG); | ||
| 199 | hwif->OUTB(tasklets[4], IDE_SECTOR_REG); | ||
| 200 | hwif->OUTB(tasklets[5], IDE_LCYL_REG); | ||
| 201 | hwif->OUTB(tasklets[6], IDE_HCYL_REG); | ||
| 202 | hwif->OUTB(0x00|drive->select.all,IDE_SELECT_REG); | ||
| 203 | } else { | 229 | } else { |
| 204 | hwif->OUTB(0x00, IDE_FEATURE_REG); | 230 | tf->nsect = nsectors & 0xff; |
| 205 | hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG); | 231 | tf->lbal = block; |
| 206 | hwif->OUTB(block, IDE_SECTOR_REG); | 232 | tf->lbam = block >>= 8; |
| 207 | hwif->OUTB(block>>=8, IDE_LCYL_REG); | 233 | tf->lbah = block >>= 8; |
| 208 | hwif->OUTB(block>>=8, IDE_HCYL_REG); | 234 | tf->device = (block >> 8) & 0xf; |
| 209 | hwif->OUTB(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG); | ||
| 210 | } | 235 | } |
| 211 | } else { | 236 | } else { |
| 212 | unsigned int sect,head,cyl,track; | 237 | unsigned int sect,head,cyl,track; |
| 213 | track = (int)block / drive->sect; | 238 | track = (int)block / drive->sect; |
| 214 | sect = (int)block % drive->sect + 1; | 239 | sect = (int)block % drive->sect + 1; |
| 215 | hwif->OUTB(sect, IDE_SECTOR_REG); | ||
| 216 | head = track % drive->head; | 240 | head = track % drive->head; |
| 217 | cyl = track / drive->head; | 241 | cyl = track / drive->head; |
| 218 | 242 | ||
| 219 | pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect); | 243 | pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect); |
| 220 | 244 | ||
| 221 | hwif->OUTB(0x00, IDE_FEATURE_REG); | 245 | tf->nsect = nsectors & 0xff; |
| 222 | hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG); | 246 | tf->lbal = sect; |
| 223 | hwif->OUTB(cyl, IDE_LCYL_REG); | 247 | tf->lbam = cyl; |
| 224 | hwif->OUTB(cyl>>8, IDE_HCYL_REG); | 248 | tf->lbah = cyl >> 8; |
| 225 | hwif->OUTB(head|drive->select.all,IDE_SELECT_REG); | 249 | tf->device = head; |
| 226 | } | 250 | } |
| 227 | 251 | ||
| 228 | if (dma) { | 252 | if (rq_data_dir(rq)) |
| 229 | if (!hwif->dma_setup(drive)) { | 253 | task.tf_flags |= IDE_TFLAG_WRITE; |
| 230 | if (rq_data_dir(rq)) { | ||
| 231 | command = lba48 ? WIN_WRITEDMA_EXT : WIN_WRITEDMA; | ||
| 232 | if (drive->vdma) | ||
| 233 | command = lba48 ? WIN_WRITE_EXT: WIN_WRITE; | ||
| 234 | } else { | ||
| 235 | command = lba48 ? WIN_READDMA_EXT : WIN_READDMA; | ||
| 236 | if (drive->vdma) | ||
| 237 | command = lba48 ? WIN_READ_EXT: WIN_READ; | ||
| 238 | } | ||
| 239 | hwif->dma_exec_cmd(drive, command); | ||
| 240 | hwif->dma_start(drive); | ||
| 241 | return ide_started; | ||
| 242 | } | ||
| 243 | /* fallback to PIO */ | ||
| 244 | ide_init_sg_cmd(drive, rq); | ||
| 245 | } | ||
| 246 | 254 | ||
| 247 | if (rq_data_dir(rq) == READ) { | 255 | ide_tf_set_cmd(drive, &task, dma); |
| 256 | if (!dma) | ||
| 257 | hwif->data_phase = task.data_phase; | ||
| 258 | task.rq = rq; | ||
| 248 | 259 | ||
| 249 | if (drive->mult_count) { | 260 | rc = do_rw_taskfile(drive, &task); |
| 250 | hwif->data_phase = TASKFILE_MULTI_IN; | ||
| 251 | command = lba48 ? WIN_MULTREAD_EXT : WIN_MULTREAD; | ||
| 252 | } else { | ||
| 253 | hwif->data_phase = TASKFILE_IN; | ||
| 254 | command = lba48 ? WIN_READ_EXT : WIN_READ; | ||
| 255 | } | ||
| 256 | 261 | ||
| 257 | ide_execute_command(drive, command, &task_in_intr, WAIT_CMD, NULL); | 262 | if (rc == ide_stopped && dma) { |
| 258 | return ide_started; | 263 | /* fallback to PIO */ |
| 259 | } else { | 264 | task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK; |
| 260 | if (drive->mult_count) { | 265 | ide_tf_set_cmd(drive, &task, 0); |
| 261 | hwif->data_phase = TASKFILE_MULTI_OUT; | 266 | hwif->data_phase = task.data_phase; |
| 262 | command = lba48 ? WIN_MULTWRITE_EXT : WIN_MULTWRITE; | 267 | ide_init_sg_cmd(drive, rq); |
| 263 | } else { | 268 | rc = do_rw_taskfile(drive, &task); |
| 264 | hwif->data_phase = TASKFILE_OUT; | ||
| 265 | command = lba48 ? WIN_WRITE_EXT : WIN_WRITE; | ||
| 266 | } | ||
| 267 | |||
| 268 | /* FIXME: ->OUTBSYNC ? */ | ||
| 269 | hwif->OUTB(command, IDE_COMMAND_REG); | ||
| 270 | |||
| 271 | return pre_task_out_intr(drive, rq); | ||
| 272 | } | 269 | } |
| 270 | |||
| 271 | return rc; | ||
| 273 | } | 272 | } |
| 274 | 273 | ||
| 275 | /* | 274 | /* |
| @@ -307,57 +306,29 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s | |||
| 307 | * Queries for true maximum capacity of the drive. | 306 | * Queries for true maximum capacity of the drive. |
| 308 | * Returns maximum LBA address (> 0) of the drive, 0 if failed. | 307 | * Returns maximum LBA address (> 0) of the drive, 0 if failed. |
| 309 | */ | 308 | */ |
| 310 | static unsigned long idedisk_read_native_max_address(ide_drive_t *drive) | 309 | static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) |
| 311 | { | 310 | { |
| 312 | ide_task_t args; | 311 | ide_task_t args; |
| 313 | unsigned long addr = 0; | 312 | struct ide_taskfile *tf = &args.tf; |
| 313 | u64 addr = 0; | ||
| 314 | 314 | ||
| 315 | /* Create IDE/ATA command request structure */ | 315 | /* Create IDE/ATA command request structure */ |
| 316 | memset(&args, 0, sizeof(ide_task_t)); | 316 | memset(&args, 0, sizeof(ide_task_t)); |
| 317 | args.tfRegister[IDE_SELECT_OFFSET] = 0x40; | 317 | if (lba48) |
| 318 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_READ_NATIVE_MAX; | 318 | tf->command = WIN_READ_NATIVE_MAX_EXT; |
| 319 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 319 | else |
| 320 | args.handler = &task_no_data_intr; | 320 | tf->command = WIN_READ_NATIVE_MAX; |
| 321 | tf->device = ATA_LBA; | ||
| 322 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | ||
| 323 | if (lba48) | ||
| 324 | args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB); | ||
| 321 | /* submit command request */ | 325 | /* submit command request */ |
| 322 | ide_raw_taskfile(drive, &args, NULL); | 326 | ide_no_data_taskfile(drive, &args); |
| 323 | 327 | ||
| 324 | /* if OK, compute maximum address value */ | 328 | /* if OK, compute maximum address value */ |
| 325 | if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) { | 329 | if ((tf->status & 0x01) == 0) |
| 326 | addr = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24) | 330 | addr = ide_get_lba_addr(tf, lba48) + 1; |
| 327 | | ((args.tfRegister[ IDE_HCYL_OFFSET] ) << 16) | ||
| 328 | | ((args.tfRegister[ IDE_LCYL_OFFSET] ) << 8) | ||
| 329 | | ((args.tfRegister[IDE_SECTOR_OFFSET] )); | ||
| 330 | addr++; /* since the return value is (maxlba - 1), we add 1 */ | ||
| 331 | } | ||
| 332 | return addr; | ||
| 333 | } | ||
| 334 | |||
| 335 | static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive) | ||
| 336 | { | ||
| 337 | ide_task_t args; | ||
| 338 | unsigned long long addr = 0; | ||
| 339 | |||
| 340 | /* Create IDE/ATA command request structure */ | ||
| 341 | memset(&args, 0, sizeof(ide_task_t)); | ||
| 342 | 331 | ||
| 343 | args.tfRegister[IDE_SELECT_OFFSET] = 0x40; | ||
| 344 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_READ_NATIVE_MAX_EXT; | ||
| 345 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | ||
| 346 | args.handler = &task_no_data_intr; | ||
| 347 | /* submit command request */ | ||
| 348 | ide_raw_taskfile(drive, &args, NULL); | ||
| 349 | |||
| 350 | /* if OK, compute maximum address value */ | ||
| 351 | if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) { | ||
| 352 | u32 high = (args.hobRegister[IDE_HCYL_OFFSET] << 16) | | ||
| 353 | (args.hobRegister[IDE_LCYL_OFFSET] << 8) | | ||
| 354 | args.hobRegister[IDE_SECTOR_OFFSET]; | ||
| 355 | u32 low = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) | | ||
| 356 | ((args.tfRegister[IDE_LCYL_OFFSET])<<8) | | ||
| 357 | (args.tfRegister[IDE_SECTOR_OFFSET]); | ||
| 358 | addr = ((__u64)high << 24) | low; | ||
| 359 | addr++; /* since the return value is (maxlba - 1), we add 1 */ | ||
| 360 | } | ||
| 361 | return addr; | 332 | return addr; |
| 362 | } | 333 | } |
| 363 | 334 | ||
| @@ -365,67 +336,37 @@ static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive | |||
| 365 | * Sets maximum virtual LBA address of the drive. | 336 | * Sets maximum virtual LBA address of the drive. |
| 366 | * Returns new maximum virtual LBA address (> 0) or 0 on failure. | 337 | * Returns new maximum virtual LBA address (> 0) or 0 on failure. |
| 367 | */ | 338 | */ |
| 368 | static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long addr_req) | 339 | static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) |
| 369 | { | 340 | { |
| 370 | ide_task_t args; | 341 | ide_task_t args; |
| 371 | unsigned long addr_set = 0; | 342 | struct ide_taskfile *tf = &args.tf; |
| 372 | 343 | u64 addr_set = 0; | |
| 373 | addr_req--; | ||
| 374 | /* Create IDE/ATA command request structure */ | ||
| 375 | memset(&args, 0, sizeof(ide_task_t)); | ||
| 376 | args.tfRegister[IDE_SECTOR_OFFSET] = ((addr_req >> 0) & 0xff); | ||
| 377 | args.tfRegister[IDE_LCYL_OFFSET] = ((addr_req >> 8) & 0xff); | ||
| 378 | args.tfRegister[IDE_HCYL_OFFSET] = ((addr_req >> 16) & 0xff); | ||
| 379 | args.tfRegister[IDE_SELECT_OFFSET] = ((addr_req >> 24) & 0x0f) | 0x40; | ||
| 380 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SET_MAX; | ||
| 381 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | ||
| 382 | args.handler = &task_no_data_intr; | ||
| 383 | /* submit command request */ | ||
| 384 | ide_raw_taskfile(drive, &args, NULL); | ||
| 385 | /* if OK, read new maximum address value */ | ||
| 386 | if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) { | ||
| 387 | addr_set = ((args.tfRegister[IDE_SELECT_OFFSET] & 0x0f) << 24) | ||
| 388 | | ((args.tfRegister[ IDE_HCYL_OFFSET] ) << 16) | ||
| 389 | | ((args.tfRegister[ IDE_LCYL_OFFSET] ) << 8) | ||
| 390 | | ((args.tfRegister[IDE_SECTOR_OFFSET] )); | ||
| 391 | addr_set++; | ||
| 392 | } | ||
| 393 | return addr_set; | ||
| 394 | } | ||
| 395 | |||
| 396 | static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsigned long long addr_req) | ||
| 397 | { | ||
| 398 | ide_task_t args; | ||
| 399 | unsigned long long addr_set = 0; | ||
| 400 | 344 | ||
| 401 | addr_req--; | 345 | addr_req--; |
| 402 | /* Create IDE/ATA command request structure */ | 346 | /* Create IDE/ATA command request structure */ |
| 403 | memset(&args, 0, sizeof(ide_task_t)); | 347 | memset(&args, 0, sizeof(ide_task_t)); |
| 404 | args.tfRegister[IDE_SECTOR_OFFSET] = ((addr_req >> 0) & 0xff); | 348 | tf->lbal = (addr_req >> 0) & 0xff; |
| 405 | args.tfRegister[IDE_LCYL_OFFSET] = ((addr_req >>= 8) & 0xff); | 349 | tf->lbam = (addr_req >>= 8) & 0xff; |
| 406 | args.tfRegister[IDE_HCYL_OFFSET] = ((addr_req >>= 8) & 0xff); | 350 | tf->lbah = (addr_req >>= 8) & 0xff; |
| 407 | args.tfRegister[IDE_SELECT_OFFSET] = 0x40; | 351 | if (lba48) { |
| 408 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SET_MAX_EXT; | 352 | tf->hob_lbal = (addr_req >>= 8) & 0xff; |
| 409 | args.hobRegister[IDE_SECTOR_OFFSET] = (addr_req >>= 8) & 0xff; | 353 | tf->hob_lbam = (addr_req >>= 8) & 0xff; |
| 410 | args.hobRegister[IDE_LCYL_OFFSET] = (addr_req >>= 8) & 0xff; | 354 | tf->hob_lbah = (addr_req >>= 8) & 0xff; |
| 411 | args.hobRegister[IDE_HCYL_OFFSET] = (addr_req >>= 8) & 0xff; | 355 | tf->command = WIN_SET_MAX_EXT; |
| 412 | args.hobRegister[IDE_SELECT_OFFSET] = 0x40; | 356 | } else { |
| 413 | args.hobRegister[IDE_CONTROL_OFFSET_HOB]= (drive->ctl|0x80); | 357 | tf->device = (addr_req >>= 8) & 0x0f; |
| 414 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 358 | tf->command = WIN_SET_MAX; |
| 415 | args.handler = &task_no_data_intr; | 359 | } |
| 360 | tf->device |= ATA_LBA; | ||
| 361 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | ||
| 362 | if (lba48) | ||
| 363 | args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_OUT_HOB); | ||
| 416 | /* submit command request */ | 364 | /* submit command request */ |
| 417 | ide_raw_taskfile(drive, &args, NULL); | 365 | ide_no_data_taskfile(drive, &args); |
| 418 | /* if OK, compute maximum address value */ | 366 | /* if OK, compute maximum address value */ |
| 419 | if ((args.tfRegister[IDE_STATUS_OFFSET] & 0x01) == 0) { | 367 | if ((tf->status & 0x01) == 0) |
| 420 | u32 high = (args.hobRegister[IDE_HCYL_OFFSET] << 16) | | 368 | addr_set = ide_get_lba_addr(tf, lba48) + 1; |
| 421 | (args.hobRegister[IDE_LCYL_OFFSET] << 8) | | 369 | |
| 422 | args.hobRegister[IDE_SECTOR_OFFSET]; | ||
| 423 | u32 low = ((args.tfRegister[IDE_HCYL_OFFSET])<<16) | | ||
| 424 | ((args.tfRegister[IDE_LCYL_OFFSET])<<8) | | ||
| 425 | (args.tfRegister[IDE_SECTOR_OFFSET]); | ||
| 426 | addr_set = ((__u64)high << 24) | low; | ||
| 427 | addr_set++; | ||
| 428 | } | ||
| 429 | return addr_set; | 370 | return addr_set; |
| 430 | } | 371 | } |
| 431 | 372 | ||
| @@ -471,10 +412,8 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
| 471 | int lba48 = idedisk_supports_lba48(drive->id); | 412 | int lba48 = idedisk_supports_lba48(drive->id); |
| 472 | 413 | ||
| 473 | capacity = drive->capacity64; | 414 | capacity = drive->capacity64; |
| 474 | if (lba48) | 415 | |
| 475 | set_max = idedisk_read_native_max_address_ext(drive); | 416 | set_max = idedisk_read_native_max_address(drive, lba48); |
| 476 | else | ||
| 477 | set_max = idedisk_read_native_max_address(drive); | ||
| 478 | 417 | ||
| 479 | if (ide_in_drive_list(drive->id, hpa_list)) { | 418 | if (ide_in_drive_list(drive->id, hpa_list)) { |
| 480 | /* | 419 | /* |
| @@ -495,10 +434,8 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
| 495 | capacity, sectors_to_MB(capacity), | 434 | capacity, sectors_to_MB(capacity), |
| 496 | set_max, sectors_to_MB(set_max)); | 435 | set_max, sectors_to_MB(set_max)); |
| 497 | 436 | ||
| 498 | if (lba48) | 437 | set_max = idedisk_set_max_address(drive, set_max, lba48); |
| 499 | set_max = idedisk_set_max_address_ext(drive, set_max); | 438 | |
| 500 | else | ||
| 501 | set_max = idedisk_set_max_address(drive, set_max); | ||
| 502 | if (set_max) { | 439 | if (set_max) { |
| 503 | drive->capacity64 = set_max; | 440 | drive->capacity64 = set_max; |
| 504 | printk(KERN_INFO "%s: Host Protected Area disabled.\n", | 441 | printk(KERN_INFO "%s: Host Protected Area disabled.\n", |
| @@ -556,32 +493,32 @@ static sector_t idedisk_capacity (ide_drive_t *drive) | |||
| 556 | static int smart_enable(ide_drive_t *drive) | 493 | static int smart_enable(ide_drive_t *drive) |
| 557 | { | 494 | { |
| 558 | ide_task_t args; | 495 | ide_task_t args; |
| 496 | struct ide_taskfile *tf = &args.tf; | ||
| 559 | 497 | ||
| 560 | memset(&args, 0, sizeof(ide_task_t)); | 498 | memset(&args, 0, sizeof(ide_task_t)); |
| 561 | args.tfRegister[IDE_FEATURE_OFFSET] = SMART_ENABLE; | 499 | tf->feature = SMART_ENABLE; |
| 562 | args.tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS; | 500 | tf->lbam = SMART_LCYL_PASS; |
| 563 | args.tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS; | 501 | tf->lbah = SMART_HCYL_PASS; |
| 564 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SMART; | 502 | tf->command = WIN_SMART; |
| 565 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 503 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 566 | args.handler = &task_no_data_intr; | 504 | return ide_no_data_taskfile(drive, &args); |
| 567 | return ide_raw_taskfile(drive, &args, NULL); | ||
| 568 | } | 505 | } |
| 569 | 506 | ||
| 570 | static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) | 507 | static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) |
| 571 | { | 508 | { |
| 572 | ide_task_t args; | 509 | ide_task_t args; |
| 510 | struct ide_taskfile *tf = &args.tf; | ||
| 573 | 511 | ||
| 574 | memset(&args, 0, sizeof(ide_task_t)); | 512 | memset(&args, 0, sizeof(ide_task_t)); |
| 575 | args.tfRegister[IDE_FEATURE_OFFSET] = sub_cmd; | 513 | tf->feature = sub_cmd; |
| 576 | args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01; | 514 | tf->nsect = 0x01; |
| 577 | args.tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS; | 515 | tf->lbam = SMART_LCYL_PASS; |
| 578 | args.tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS; | 516 | tf->lbah = SMART_HCYL_PASS; |
| 579 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SMART; | 517 | tf->command = WIN_SMART; |
| 580 | args.command_type = IDE_DRIVE_TASK_IN; | 518 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 581 | args.data_phase = TASKFILE_IN; | 519 | args.data_phase = TASKFILE_IN; |
| 582 | args.handler = &task_in_intr; | ||
| 583 | (void) smart_enable(drive); | 520 | (void) smart_enable(drive); |
| 584 | return ide_raw_taskfile(drive, &args, buf); | 521 | return ide_raw_taskfile(drive, &args, buf, 1); |
| 585 | } | 522 | } |
| 586 | 523 | ||
| 587 | static int proc_idedisk_read_cache | 524 | static int proc_idedisk_read_cache |
| @@ -659,19 +596,20 @@ static ide_proc_entry_t idedisk_proc[] = { | |||
| 659 | static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | 596 | static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) |
| 660 | { | 597 | { |
| 661 | ide_drive_t *drive = q->queuedata; | 598 | ide_drive_t *drive = q->queuedata; |
| 599 | ide_task_t task; | ||
| 662 | 600 | ||
| 663 | memset(rq->cmd, 0, sizeof(rq->cmd)); | 601 | memset(&task, 0, sizeof(task)); |
| 664 | |||
| 665 | if (ide_id_has_flush_cache_ext(drive->id) && | 602 | if (ide_id_has_flush_cache_ext(drive->id) && |
| 666 | (drive->capacity64 >= (1UL << 28))) | 603 | (drive->capacity64 >= (1UL << 28))) |
| 667 | rq->cmd[0] = WIN_FLUSH_CACHE_EXT; | 604 | task.tf.command = WIN_FLUSH_CACHE_EXT; |
| 668 | else | 605 | else |
| 669 | rq->cmd[0] = WIN_FLUSH_CACHE; | 606 | task.tf.command = WIN_FLUSH_CACHE; |
| 670 | 607 | task.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | |
| 608 | task.data_phase = TASKFILE_NO_DATA; | ||
| 671 | 609 | ||
| 672 | rq->cmd_type = REQ_TYPE_ATA_TASK; | 610 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; |
| 673 | rq->cmd_flags |= REQ_SOFTBARRIER; | 611 | rq->cmd_flags |= REQ_SOFTBARRIER; |
| 674 | rq->buffer = rq->cmd; | 612 | rq->special = &task; |
| 675 | } | 613 | } |
| 676 | 614 | ||
| 677 | /* | 615 | /* |
| @@ -753,12 +691,11 @@ static int write_cache(ide_drive_t *drive, int arg) | |||
| 753 | 691 | ||
| 754 | if (ide_id_has_flush_cache(drive->id)) { | 692 | if (ide_id_has_flush_cache(drive->id)) { |
| 755 | memset(&args, 0, sizeof(ide_task_t)); | 693 | memset(&args, 0, sizeof(ide_task_t)); |
| 756 | args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? | 694 | args.tf.feature = arg ? |
| 757 | SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; | 695 | SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE; |
| 758 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES; | 696 | args.tf.command = WIN_SETFEATURES; |
| 759 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 697 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 760 | args.handler = &task_no_data_intr; | 698 | err = ide_no_data_taskfile(drive, &args); |
| 761 | err = ide_raw_taskfile(drive, &args, NULL); | ||
| 762 | if (err == 0) | 699 | if (err == 0) |
| 763 | drive->wcache = arg; | 700 | drive->wcache = arg; |
| 764 | } | 701 | } |
| @@ -774,12 +711,11 @@ static int do_idedisk_flushcache (ide_drive_t *drive) | |||
| 774 | 711 | ||
| 775 | memset(&args, 0, sizeof(ide_task_t)); | 712 | memset(&args, 0, sizeof(ide_task_t)); |
| 776 | if (ide_id_has_flush_cache_ext(drive->id)) | 713 | if (ide_id_has_flush_cache_ext(drive->id)) |
| 777 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT; | 714 | args.tf.command = WIN_FLUSH_CACHE_EXT; |
| 778 | else | 715 | else |
| 779 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE; | 716 | args.tf.command = WIN_FLUSH_CACHE; |
| 780 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 717 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 781 | args.handler = &task_no_data_intr; | 718 | return ide_no_data_taskfile(drive, &args); |
| 782 | return ide_raw_taskfile(drive, &args, NULL); | ||
| 783 | } | 719 | } |
| 784 | 720 | ||
| 785 | static int set_acoustic (ide_drive_t *drive, int arg) | 721 | static int set_acoustic (ide_drive_t *drive, int arg) |
| @@ -790,13 +726,11 @@ static int set_acoustic (ide_drive_t *drive, int arg) | |||
| 790 | return -EINVAL; | 726 | return -EINVAL; |
| 791 | 727 | ||
| 792 | memset(&args, 0, sizeof(ide_task_t)); | 728 | memset(&args, 0, sizeof(ide_task_t)); |
| 793 | args.tfRegister[IDE_FEATURE_OFFSET] = (arg) ? SETFEATURES_EN_AAM : | 729 | args.tf.feature = arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM; |
| 794 | SETFEATURES_DIS_AAM; | 730 | args.tf.nsect = arg; |
| 795 | args.tfRegister[IDE_NSECTOR_OFFSET] = arg; | 731 | args.tf.command = WIN_SETFEATURES; |
| 796 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SETFEATURES; | 732 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 797 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 733 | ide_no_data_taskfile(drive, &args); |
| 798 | args.handler = &task_no_data_intr; | ||
| 799 | ide_raw_taskfile(drive, &args, NULL); | ||
| 800 | drive->acoustic = arg; | 734 | drive->acoustic = arg; |
| 801 | return 0; | 735 | return 0; |
| 802 | } | 736 | } |
| @@ -1057,16 +991,15 @@ static int idedisk_open(struct inode *inode, struct file *filp) | |||
| 1057 | if (drive->removable && idkp->openers == 1) { | 991 | if (drive->removable && idkp->openers == 1) { |
| 1058 | ide_task_t args; | 992 | ide_task_t args; |
| 1059 | memset(&args, 0, sizeof(ide_task_t)); | 993 | memset(&args, 0, sizeof(ide_task_t)); |
| 1060 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK; | 994 | args.tf.command = WIN_DOORLOCK; |
| 1061 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 995 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 1062 | args.handler = &task_no_data_intr; | ||
| 1063 | check_disk_change(inode->i_bdev); | 996 | check_disk_change(inode->i_bdev); |
| 1064 | /* | 997 | /* |
| 1065 | * Ignore the return code from door_lock, | 998 | * Ignore the return code from door_lock, |
| 1066 | * since the open() has already succeeded, | 999 | * since the open() has already succeeded, |
| 1067 | * and the door_lock is irrelevant at this point. | 1000 | * and the door_lock is irrelevant at this point. |
| 1068 | */ | 1001 | */ |
| 1069 | if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) | 1002 | if (drive->doorlocking && ide_no_data_taskfile(drive, &args)) |
| 1070 | drive->doorlocking = 0; | 1003 | drive->doorlocking = 0; |
| 1071 | } | 1004 | } |
| 1072 | return 0; | 1005 | return 0; |
| @@ -1084,10 +1017,9 @@ static int idedisk_release(struct inode *inode, struct file *filp) | |||
| 1084 | if (drive->removable && idkp->openers == 1) { | 1017 | if (drive->removable && idkp->openers == 1) { |
| 1085 | ide_task_t args; | 1018 | ide_task_t args; |
| 1086 | memset(&args, 0, sizeof(ide_task_t)); | 1019 | memset(&args, 0, sizeof(ide_task_t)); |
| 1087 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORUNLOCK; | 1020 | args.tf.command = WIN_DOORUNLOCK; |
| 1088 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 1021 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 1089 | args.handler = &task_no_data_intr; | 1022 | if (drive->doorlocking && ide_no_data_taskfile(drive, &args)) |
| 1090 | if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) | ||
| 1091 | drive->doorlocking = 0; | 1023 | drive->doorlocking = 0; |
| 1092 | } | 1024 | } |
| 1093 | 1025 | ||
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 4703837bf1fc..18c78ad2b31e 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
| @@ -491,10 +491,6 @@ EXPORT_SYMBOL(ide_dma_host_on); | |||
| 491 | 491 | ||
| 492 | int __ide_dma_on (ide_drive_t *drive) | 492 | int __ide_dma_on (ide_drive_t *drive) |
| 493 | { | 493 | { |
| 494 | /* consult the list of known "bad" drives */ | ||
| 495 | if (__ide_dma_bad_drive(drive)) | ||
| 496 | return 1; | ||
| 497 | |||
| 498 | drive->using_dma = 1; | 494 | drive->using_dma = 1; |
| 499 | ide_toggle_bounce(drive, 1); | 495 | ide_toggle_bounce(drive, 1); |
| 500 | 496 | ||
| @@ -827,22 +823,19 @@ int ide_set_dma(ide_drive_t *drive) | |||
| 827 | ide_hwif_t *hwif = drive->hwif; | 823 | ide_hwif_t *hwif = drive->hwif; |
| 828 | int rc; | 824 | int rc; |
| 829 | 825 | ||
| 830 | rc = ide_dma_check(drive); | 826 | /* |
| 827 | * Force DMAing for the beginning of the check. | ||
| 828 | * Some chipsets appear to do interesting | ||
| 829 | * things, if not checked and cleared. | ||
| 830 | * PARANOIA!!! | ||
| 831 | */ | ||
| 832 | hwif->dma_off_quietly(drive); | ||
| 831 | 833 | ||
| 832 | switch(rc) { | 834 | rc = ide_dma_check(drive); |
| 833 | case -1: /* DMA needs to be disabled */ | 835 | if (rc) |
| 834 | hwif->dma_off_quietly(drive); | 836 | return rc; |
| 835 | return -1; | ||
| 836 | case 0: /* DMA needs to be enabled */ | ||
| 837 | return hwif->ide_dma_on(drive); | ||
| 838 | case 1: /* DMA setting cannot be changed */ | ||
| 839 | break; | ||
| 840 | default: | ||
| 841 | BUG(); | ||
| 842 | break; | ||
| 843 | } | ||
| 844 | 837 | ||
| 845 | return rc; | 838 | return hwif->ide_dma_on(drive); |
| 846 | } | 839 | } |
| 847 | 840 | ||
| 848 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI | 841 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI |
| @@ -968,11 +961,6 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports) | |||
| 968 | 961 | ||
| 969 | hwif->dma_base = base; | 962 | hwif->dma_base = base; |
| 970 | 963 | ||
| 971 | if (hwif->mate) | ||
| 972 | hwif->dma_master = hwif->channel ? hwif->mate->dma_base : base; | ||
| 973 | else | ||
| 974 | hwif->dma_master = base; | ||
| 975 | |||
| 976 | if (!(hwif->dma_command)) | 964 | if (!(hwif->dma_command)) |
| 977 | hwif->dma_command = hwif->dma_base; | 965 | hwif->dma_command = hwif->dma_base; |
| 978 | if (!(hwif->dma_vendor1)) | 966 | if (!(hwif->dma_vendor1)) |
| @@ -1014,8 +1002,6 @@ void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports) | |||
| 1014 | hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio"); | 1002 | hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio"); |
| 1015 | } | 1003 | } |
| 1016 | printk("\n"); | 1004 | printk("\n"); |
| 1017 | |||
| 1018 | BUG_ON(!hwif->dma_master); | ||
| 1019 | } | 1005 | } |
| 1020 | 1006 | ||
| 1021 | EXPORT_SYMBOL_GPL(ide_setup_dma); | 1007 | EXPORT_SYMBOL_GPL(ide_setup_dma); |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 04a357808f2e..ff8232ef9659 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
| @@ -369,27 +369,6 @@ typedef struct ide_floppy_obj { | |||
| 369 | #define IDEFLOPPY_IOCTL_FORMAT_START 0x4602 | 369 | #define IDEFLOPPY_IOCTL_FORMAT_START 0x4602 |
| 370 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 | 370 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 |
| 371 | 371 | ||
| 372 | #if 0 | ||
| 373 | /* | ||
| 374 | * Special requests for our block device strategy routine. | ||
| 375 | */ | ||
| 376 | #define IDEFLOPPY_FIRST_RQ 90 | ||
| 377 | |||
| 378 | /* | ||
| 379 | * IDEFLOPPY_PC_RQ is used to queue a packet command in the request queue. | ||
| 380 | */ | ||
| 381 | #define IDEFLOPPY_PC_RQ 90 | ||
| 382 | |||
| 383 | #define IDEFLOPPY_LAST_RQ 90 | ||
| 384 | |||
| 385 | /* | ||
| 386 | * A macro which can be used to check if a given request command | ||
| 387 | * originated in the driver or in the buffer cache layer. | ||
| 388 | */ | ||
| 389 | #define IDEFLOPPY_RQ_CMD(cmd) ((cmd >= IDEFLOPPY_FIRST_RQ) && (cmd <= IDEFLOPPY_LAST_RQ)) | ||
| 390 | |||
| 391 | #endif | ||
| 392 | |||
| 393 | /* | 372 | /* |
| 394 | * Error codes which are returned in rq->errors to the higher part | 373 | * Error codes which are returned in rq->errors to the higher part |
| 395 | * of the driver. | 374 | * of the driver. |
| @@ -793,9 +772,8 @@ static void idefloppy_retry_pc (ide_drive_t *drive) | |||
| 793 | { | 772 | { |
| 794 | idefloppy_pc_t *pc; | 773 | idefloppy_pc_t *pc; |
| 795 | struct request *rq; | 774 | struct request *rq; |
| 796 | atapi_error_t error; | ||
| 797 | 775 | ||
| 798 | error.all = HWIF(drive)->INB(IDE_ERROR_REG); | 776 | (void)drive->hwif->INB(IDE_ERROR_REG); |
| 799 | pc = idefloppy_next_pc_storage(drive); | 777 | pc = idefloppy_next_pc_storage(drive); |
| 800 | rq = idefloppy_next_rq_storage(drive); | 778 | rq = idefloppy_next_rq_storage(drive); |
| 801 | idefloppy_create_request_sense_cmd(pc); | 779 | idefloppy_create_request_sense_cmd(pc); |
| @@ -809,12 +787,12 @@ static void idefloppy_retry_pc (ide_drive_t *drive) | |||
| 809 | static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | 787 | static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) |
| 810 | { | 788 | { |
| 811 | idefloppy_floppy_t *floppy = drive->driver_data; | 789 | idefloppy_floppy_t *floppy = drive->driver_data; |
| 812 | atapi_status_t status; | 790 | ide_hwif_t *hwif = drive->hwif; |
| 813 | atapi_bcount_t bcount; | ||
| 814 | atapi_ireason_t ireason; | ||
| 815 | idefloppy_pc_t *pc = floppy->pc; | 791 | idefloppy_pc_t *pc = floppy->pc; |
| 816 | struct request *rq = pc->rq; | 792 | struct request *rq = pc->rq; |
| 817 | unsigned int temp; | 793 | unsigned int temp; |
| 794 | u16 bcount; | ||
| 795 | u8 stat, ireason; | ||
| 818 | 796 | ||
| 819 | debug_log(KERN_INFO "ide-floppy: Reached %s interrupt handler\n", | 797 | debug_log(KERN_INFO "ide-floppy: Reached %s interrupt handler\n", |
| 820 | __FUNCTION__); | 798 | __FUNCTION__); |
| @@ -830,16 +808,16 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
| 830 | } | 808 | } |
| 831 | 809 | ||
| 832 | /* Clear the interrupt */ | 810 | /* Clear the interrupt */ |
| 833 | status.all = HWIF(drive)->INB(IDE_STATUS_REG); | 811 | stat = drive->hwif->INB(IDE_STATUS_REG); |
| 834 | 812 | ||
| 835 | if (!status.b.drq) { /* No more interrupts */ | 813 | if ((stat & DRQ_STAT) == 0) { /* No more interrupts */ |
| 836 | debug_log(KERN_INFO "Packet command completed, %d bytes " | 814 | debug_log(KERN_INFO "Packet command completed, %d bytes " |
| 837 | "transferred\n", pc->actually_transferred); | 815 | "transferred\n", pc->actually_transferred); |
| 838 | clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); | 816 | clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); |
| 839 | 817 | ||
| 840 | local_irq_enable_in_hardirq(); | 818 | local_irq_enable_in_hardirq(); |
| 841 | 819 | ||
| 842 | if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) { | 820 | if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) { |
| 843 | /* Error detected */ | 821 | /* Error detected */ |
| 844 | debug_log(KERN_INFO "ide-floppy: %s: I/O error\n", | 822 | debug_log(KERN_INFO "ide-floppy: %s: I/O error\n", |
| 845 | drive->name); | 823 | drive->name); |
| @@ -870,32 +848,32 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
| 870 | } | 848 | } |
| 871 | 849 | ||
| 872 | /* Get the number of bytes to transfer */ | 850 | /* Get the number of bytes to transfer */ |
| 873 | bcount.b.high = HWIF(drive)->INB(IDE_BCOUNTH_REG); | 851 | bcount = (hwif->INB(IDE_BCOUNTH_REG) << 8) | |
| 874 | bcount.b.low = HWIF(drive)->INB(IDE_BCOUNTL_REG); | 852 | hwif->INB(IDE_BCOUNTL_REG); |
| 875 | /* on this interrupt */ | 853 | /* on this interrupt */ |
| 876 | ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); | 854 | ireason = hwif->INB(IDE_IREASON_REG); |
| 877 | 855 | ||
| 878 | if (ireason.b.cod) { | 856 | if (ireason & CD) { |
| 879 | printk(KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n"); | 857 | printk(KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n"); |
| 880 | return ide_do_reset(drive); | 858 | return ide_do_reset(drive); |
| 881 | } | 859 | } |
| 882 | if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { | 860 | if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) { |
| 883 | /* Hopefully, we will never get here */ | 861 | /* Hopefully, we will never get here */ |
| 884 | printk(KERN_ERR "ide-floppy: We wanted to %s, ", | 862 | printk(KERN_ERR "ide-floppy: We wanted to %s, ", |
| 885 | ireason.b.io ? "Write":"Read"); | 863 | (ireason & IO) ? "Write" : "Read"); |
| 886 | printk(KERN_ERR "but the floppy wants us to %s !\n", | 864 | printk(KERN_ERR "but the floppy wants us to %s !\n", |
| 887 | ireason.b.io ? "Read":"Write"); | 865 | (ireason & IO) ? "Read" : "Write"); |
| 888 | return ide_do_reset(drive); | 866 | return ide_do_reset(drive); |
| 889 | } | 867 | } |
| 890 | if (!test_bit(PC_WRITING, &pc->flags)) { | 868 | if (!test_bit(PC_WRITING, &pc->flags)) { |
| 891 | /* Reading - Check that we have enough space */ | 869 | /* Reading - Check that we have enough space */ |
| 892 | temp = pc->actually_transferred + bcount.all; | 870 | temp = pc->actually_transferred + bcount; |
| 893 | if (temp > pc->request_transfer) { | 871 | if (temp > pc->request_transfer) { |
| 894 | if (temp > pc->buffer_size) { | 872 | if (temp > pc->buffer_size) { |
| 895 | printk(KERN_ERR "ide-floppy: The floppy wants " | 873 | printk(KERN_ERR "ide-floppy: The floppy wants " |
| 896 | "to send us more data than expected " | 874 | "to send us more data than expected " |
| 897 | "- discarding data\n"); | 875 | "- discarding data\n"); |
| 898 | idefloppy_discard_data(drive,bcount.all); | 876 | idefloppy_discard_data(drive, bcount); |
| 899 | BUG_ON(HWGROUP(drive)->handler != NULL); | 877 | BUG_ON(HWGROUP(drive)->handler != NULL); |
| 900 | ide_set_handler(drive, | 878 | ide_set_handler(drive, |
| 901 | &idefloppy_pc_intr, | 879 | &idefloppy_pc_intr, |
| @@ -911,23 +889,21 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
| 911 | if (test_bit(PC_WRITING, &pc->flags)) { | 889 | if (test_bit(PC_WRITING, &pc->flags)) { |
| 912 | if (pc->buffer != NULL) | 890 | if (pc->buffer != NULL) |
| 913 | /* Write the current buffer */ | 891 | /* Write the current buffer */ |
| 914 | HWIF(drive)->atapi_output_bytes(drive, | 892 | hwif->atapi_output_bytes(drive, pc->current_position, |
| 915 | pc->current_position, | 893 | bcount); |
| 916 | bcount.all); | ||
| 917 | else | 894 | else |
| 918 | idefloppy_output_buffers(drive, pc, bcount.all); | 895 | idefloppy_output_buffers(drive, pc, bcount); |
| 919 | } else { | 896 | } else { |
| 920 | if (pc->buffer != NULL) | 897 | if (pc->buffer != NULL) |
| 921 | /* Read the current buffer */ | 898 | /* Read the current buffer */ |
| 922 | HWIF(drive)->atapi_input_bytes(drive, | 899 | hwif->atapi_input_bytes(drive, pc->current_position, |
| 923 | pc->current_position, | 900 | bcount); |
| 924 | bcount.all); | ||
| 925 | else | 901 | else |
| 926 | idefloppy_input_buffers(drive, pc, bcount.all); | 902 | idefloppy_input_buffers(drive, pc, bcount); |
| 927 | } | 903 | } |
| 928 | /* Update the current position */ | 904 | /* Update the current position */ |
| 929 | pc->actually_transferred += bcount.all; | 905 | pc->actually_transferred += bcount; |
| 930 | pc->current_position += bcount.all; | 906 | pc->current_position += bcount; |
| 931 | 907 | ||
| 932 | BUG_ON(HWGROUP(drive)->handler != NULL); | 908 | BUG_ON(HWGROUP(drive)->handler != NULL); |
| 933 | ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ | 909 | ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ |
| @@ -943,15 +919,15 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive) | |||
| 943 | { | 919 | { |
| 944 | ide_startstop_t startstop; | 920 | ide_startstop_t startstop; |
| 945 | idefloppy_floppy_t *floppy = drive->driver_data; | 921 | idefloppy_floppy_t *floppy = drive->driver_data; |
| 946 | atapi_ireason_t ireason; | 922 | u8 ireason; |
| 947 | 923 | ||
| 948 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | 924 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { |
| 949 | printk(KERN_ERR "ide-floppy: Strange, packet command " | 925 | printk(KERN_ERR "ide-floppy: Strange, packet command " |
| 950 | "initiated yet DRQ isn't asserted\n"); | 926 | "initiated yet DRQ isn't asserted\n"); |
| 951 | return startstop; | 927 | return startstop; |
| 952 | } | 928 | } |
| 953 | ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); | 929 | ireason = drive->hwif->INB(IDE_IREASON_REG); |
| 954 | if (!ireason.b.cod || ireason.b.io) { | 930 | if ((ireason & CD) == 0 || (ireason & IO)) { |
| 955 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while " | 931 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while " |
| 956 | "issuing a packet command\n"); | 932 | "issuing a packet command\n"); |
| 957 | return ide_do_reset(drive); | 933 | return ide_do_reset(drive); |
| @@ -991,15 +967,15 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) | |||
| 991 | { | 967 | { |
| 992 | idefloppy_floppy_t *floppy = drive->driver_data; | 968 | idefloppy_floppy_t *floppy = drive->driver_data; |
| 993 | ide_startstop_t startstop; | 969 | ide_startstop_t startstop; |
| 994 | atapi_ireason_t ireason; | 970 | u8 ireason; |
| 995 | 971 | ||
| 996 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { | 972 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { |
| 997 | printk(KERN_ERR "ide-floppy: Strange, packet command " | 973 | printk(KERN_ERR "ide-floppy: Strange, packet command " |
| 998 | "initiated yet DRQ isn't asserted\n"); | 974 | "initiated yet DRQ isn't asserted\n"); |
| 999 | return startstop; | 975 | return startstop; |
| 1000 | } | 976 | } |
| 1001 | ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); | 977 | ireason = drive->hwif->INB(IDE_IREASON_REG); |
| 1002 | if (!ireason.b.cod || ireason.b.io) { | 978 | if ((ireason & CD) == 0 || (ireason & IO)) { |
| 1003 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) " | 979 | printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) " |
| 1004 | "while issuing a packet command\n"); | 980 | "while issuing a packet command\n"); |
| 1005 | return ide_do_reset(drive); | 981 | return ide_do_reset(drive); |
| @@ -1041,21 +1017,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p | |||
| 1041 | { | 1017 | { |
| 1042 | idefloppy_floppy_t *floppy = drive->driver_data; | 1018 | idefloppy_floppy_t *floppy = drive->driver_data; |
| 1043 | ide_hwif_t *hwif = drive->hwif; | 1019 | ide_hwif_t *hwif = drive->hwif; |
| 1044 | atapi_feature_t feature; | ||
| 1045 | atapi_bcount_t bcount; | ||
| 1046 | ide_handler_t *pkt_xfer_routine; | 1020 | ide_handler_t *pkt_xfer_routine; |
| 1047 | 1021 | u16 bcount; | |
| 1048 | #if 0 /* Accessing floppy->pc is not valid here, the previous pc may be gone | 1022 | u8 dma; |
| 1049 | and have lived on another thread's stack; that stack may have become | ||
| 1050 | unmapped meanwhile (CONFIG_DEBUG_PAGEALLOC). */ | ||
| 1051 | #if IDEFLOPPY_DEBUG_BUGS | ||
| 1052 | if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD && | ||
| 1053 | pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) { | ||
| 1054 | printk(KERN_ERR "ide-floppy: possible ide-floppy.c bug - " | ||
| 1055 | "Two request sense in serial were issued\n"); | ||
| 1056 | } | ||
| 1057 | #endif /* IDEFLOPPY_DEBUG_BUGS */ | ||
| 1058 | #endif | ||
| 1059 | 1023 | ||
| 1060 | if (floppy->failed_pc == NULL && | 1024 | if (floppy->failed_pc == NULL && |
| 1061 | pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD) | 1025 | pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD) |
| @@ -1093,25 +1057,20 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p | |||
| 1093 | /* We haven't transferred any data yet */ | 1057 | /* We haven't transferred any data yet */ |
| 1094 | pc->actually_transferred = 0; | 1058 | pc->actually_transferred = 0; |
| 1095 | pc->current_position = pc->buffer; | 1059 | pc->current_position = pc->buffer; |
| 1096 | bcount.all = min(pc->request_transfer, 63 * 1024); | 1060 | bcount = min(pc->request_transfer, 63 * 1024); |
| 1097 | 1061 | ||
| 1098 | if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) | 1062 | if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) |
| 1099 | ide_dma_off(drive); | 1063 | ide_dma_off(drive); |
| 1100 | 1064 | ||
| 1101 | feature.all = 0; | 1065 | dma = 0; |
| 1102 | 1066 | ||
| 1103 | if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) | 1067 | if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) |
| 1104 | feature.b.dma = !hwif->dma_setup(drive); | 1068 | dma = !hwif->dma_setup(drive); |
| 1105 | 1069 | ||
| 1106 | if (IDE_CONTROL_REG) | 1070 | ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK | |
| 1107 | HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); | 1071 | IDE_TFLAG_OUT_DEVICE, bcount, dma); |
| 1108 | /* Use PIO/DMA */ | ||
| 1109 | HWIF(drive)->OUTB(feature.all, IDE_FEATURE_REG); | ||
| 1110 | HWIF(drive)->OUTB(bcount.b.high, IDE_BCOUNTH_REG); | ||
| 1111 | HWIF(drive)->OUTB(bcount.b.low, IDE_BCOUNTL_REG); | ||
| 1112 | HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG); | ||
| 1113 | 1072 | ||
| 1114 | if (feature.b.dma) { /* Begin DMA, if necessary */ | 1073 | if (dma) { /* Begin DMA, if necessary */ |
| 1115 | set_bit(PC_DMA_IN_PROGRESS, &pc->flags); | 1074 | set_bit(PC_DMA_IN_PROGRESS, &pc->flags); |
| 1116 | hwif->dma_start(drive); | 1075 | hwif->dma_start(drive); |
| 1117 | } | 1076 | } |
| @@ -1665,14 +1624,14 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg) | |||
| 1665 | /* Else assume format_unit has finished, and we're | 1624 | /* Else assume format_unit has finished, and we're |
| 1666 | ** at 0x10000 */ | 1625 | ** at 0x10000 */ |
| 1667 | } else { | 1626 | } else { |
| 1668 | atapi_status_t status; | ||
| 1669 | unsigned long flags; | 1627 | unsigned long flags; |
| 1628 | u8 stat; | ||
| 1670 | 1629 | ||
| 1671 | local_irq_save(flags); | 1630 | local_irq_save(flags); |
| 1672 | status.all = HWIF(drive)->INB(IDE_STATUS_REG); | 1631 | stat = drive->hwif->INB(IDE_STATUS_REG); |
| 1673 | local_irq_restore(flags); | 1632 | local_irq_restore(flags); |
| 1674 | 1633 | ||
| 1675 | progress_indication = !status.b.dsc ? 0 : 0x10000; | 1634 | progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000; |
| 1676 | } | 1635 | } |
| 1677 | if (put_user(progress_indication, arg)) | 1636 | if (put_user(progress_indication, arg)) |
| 1678 | return (-EFAULT); | 1637 | return (-EFAULT); |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index bef781fec500..2711b5a6962d 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
| @@ -189,18 +189,14 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
| 189 | return ide_stopped; | 189 | return ide_stopped; |
| 190 | } | 190 | } |
| 191 | if (ide_id_has_flush_cache_ext(drive->id)) | 191 | if (ide_id_has_flush_cache_ext(drive->id)) |
| 192 | args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE_EXT; | 192 | args->tf.command = WIN_FLUSH_CACHE_EXT; |
| 193 | else | 193 | else |
| 194 | args->tfRegister[IDE_COMMAND_OFFSET] = WIN_FLUSH_CACHE; | 194 | args->tf.command = WIN_FLUSH_CACHE; |
| 195 | args->command_type = IDE_DRIVE_TASK_NO_DATA; | 195 | goto out_do_tf; |
| 196 | args->handler = &task_no_data_intr; | ||
| 197 | return do_rw_taskfile(drive, args); | ||
| 198 | 196 | ||
| 199 | case idedisk_pm_standby: /* Suspend step 2 (standby) */ | 197 | case idedisk_pm_standby: /* Suspend step 2 (standby) */ |
| 200 | args->tfRegister[IDE_COMMAND_OFFSET] = WIN_STANDBYNOW1; | 198 | args->tf.command = WIN_STANDBYNOW1; |
| 201 | args->command_type = IDE_DRIVE_TASK_NO_DATA; | 199 | goto out_do_tf; |
| 202 | args->handler = &task_no_data_intr; | ||
| 203 | return do_rw_taskfile(drive, args); | ||
| 204 | 200 | ||
| 205 | case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */ | 201 | case idedisk_pm_restore_pio: /* Resume step 1 (restore PIO) */ |
| 206 | ide_set_max_pio(drive); | 202 | ide_set_max_pio(drive); |
| @@ -214,10 +210,8 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
| 214 | return ide_stopped; | 210 | return ide_stopped; |
| 215 | 211 | ||
| 216 | case idedisk_pm_idle: /* Resume step 2 (idle) */ | 212 | case idedisk_pm_idle: /* Resume step 2 (idle) */ |
| 217 | args->tfRegister[IDE_COMMAND_OFFSET] = WIN_IDLEIMMEDIATE; | 213 | args->tf.command = WIN_IDLEIMMEDIATE; |
| 218 | args->command_type = IDE_DRIVE_TASK_NO_DATA; | 214 | goto out_do_tf; |
| 219 | args->handler = task_no_data_intr; | ||
| 220 | return do_rw_taskfile(drive, args); | ||
| 221 | 215 | ||
| 222 | case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */ | 216 | case ide_pm_restore_dma: /* Resume step 3 (restore DMA) */ |
| 223 | /* | 217 | /* |
| @@ -227,7 +221,6 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
| 227 | */ | 221 | */ |
| 228 | if (drive->hwif->ide_dma_on == NULL) | 222 | if (drive->hwif->ide_dma_on == NULL) |
| 229 | break; | 223 | break; |
| 230 | drive->hwif->dma_off_quietly(drive); | ||
| 231 | /* | 224 | /* |
| 232 | * TODO: respect ->using_dma setting | 225 | * TODO: respect ->using_dma setting |
| 233 | */ | 226 | */ |
| @@ -236,6 +229,11 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * | |||
| 236 | } | 229 | } |
| 237 | pm->pm_step = ide_pm_state_completed; | 230 | pm->pm_step = ide_pm_state_completed; |
| 238 | return ide_stopped; | 231 | return ide_stopped; |
| 232 | |||
| 233 | out_do_tf: | ||
| 234 | args->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; | ||
| 235 | args->data_phase = TASKFILE_NO_DATA; | ||
| 236 | return do_rw_taskfile(drive, args); | ||
| 239 | } | 237 | } |
| 240 | 238 | ||
| 241 | /** | 239 | /** |
| @@ -298,6 +296,48 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) | |||
| 298 | spin_unlock_irqrestore(&ide_lock, flags); | 296 | spin_unlock_irqrestore(&ide_lock, flags); |
| 299 | } | 297 | } |
| 300 | 298 | ||
| 299 | void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | ||
| 300 | { | ||
| 301 | ide_hwif_t *hwif = drive->hwif; | ||
| 302 | struct ide_taskfile *tf = &task->tf; | ||
| 303 | |||
| 304 | if (task->tf_flags & IDE_TFLAG_IN_DATA) { | ||
| 305 | u16 data = hwif->INW(IDE_DATA_REG); | ||
| 306 | |||
| 307 | tf->data = data & 0xff; | ||
| 308 | tf->hob_data = (data >> 8) & 0xff; | ||
| 309 | } | ||
| 310 | |||
| 311 | /* be sure we're looking at the low order bits */ | ||
| 312 | hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG); | ||
| 313 | |||
| 314 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) | ||
| 315 | tf->nsect = hwif->INB(IDE_NSECTOR_REG); | ||
| 316 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) | ||
| 317 | tf->lbal = hwif->INB(IDE_SECTOR_REG); | ||
| 318 | if (task->tf_flags & IDE_TFLAG_IN_LBAM) | ||
| 319 | tf->lbam = hwif->INB(IDE_LCYL_REG); | ||
| 320 | if (task->tf_flags & IDE_TFLAG_IN_LBAH) | ||
| 321 | tf->lbah = hwif->INB(IDE_HCYL_REG); | ||
| 322 | if (task->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
| 323 | tf->device = hwif->INB(IDE_SELECT_REG); | ||
| 324 | |||
| 325 | if (task->tf_flags & IDE_TFLAG_LBA48) { | ||
| 326 | hwif->OUTB(drive->ctl | 0x80, IDE_CONTROL_REG); | ||
| 327 | |||
| 328 | if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) | ||
| 329 | tf->hob_feature = hwif->INB(IDE_FEATURE_REG); | ||
| 330 | if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
| 331 | tf->hob_nsect = hwif->INB(IDE_NSECTOR_REG); | ||
| 332 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
| 333 | tf->hob_lbal = hwif->INB(IDE_SECTOR_REG); | ||
| 334 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
| 335 | tf->hob_lbam = hwif->INB(IDE_LCYL_REG); | ||
| 336 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
| 337 | tf->hob_lbah = hwif->INB(IDE_HCYL_REG); | ||
| 338 | } | ||
| 339 | } | ||
| 340 | |||
| 301 | /** | 341 | /** |
| 302 | * ide_end_drive_cmd - end an explicit drive command | 342 | * ide_end_drive_cmd - end an explicit drive command |
| 303 | * @drive: command | 343 | * @drive: command |
| @@ -332,51 +372,22 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
| 332 | args[1] = err; | 372 | args[1] = err; |
| 333 | args[2] = hwif->INB(IDE_NSECTOR_REG); | 373 | args[2] = hwif->INB(IDE_NSECTOR_REG); |
| 334 | } | 374 | } |
| 335 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) { | ||
| 336 | u8 *args = (u8 *) rq->buffer; | ||
| 337 | if (rq->errors == 0) | ||
| 338 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | ||
| 339 | |||
| 340 | if (args) { | ||
| 341 | args[0] = stat; | ||
| 342 | args[1] = err; | ||
| 343 | /* be sure we're looking at the low order bits */ | ||
| 344 | hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG); | ||
| 345 | args[2] = hwif->INB(IDE_NSECTOR_REG); | ||
| 346 | args[3] = hwif->INB(IDE_SECTOR_REG); | ||
| 347 | args[4] = hwif->INB(IDE_LCYL_REG); | ||
| 348 | args[5] = hwif->INB(IDE_HCYL_REG); | ||
| 349 | args[6] = hwif->INB(IDE_SELECT_REG); | ||
| 350 | } | ||
| 351 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | 375 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
| 352 | ide_task_t *args = (ide_task_t *) rq->special; | 376 | ide_task_t *args = (ide_task_t *) rq->special; |
| 353 | if (rq->errors == 0) | 377 | if (rq->errors == 0) |
| 354 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); | 378 | rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); |
| 355 | 379 | ||
| 356 | if (args) { | 380 | if (args) { |
| 357 | if (args->tf_in_flags.b.data) { | 381 | struct ide_taskfile *tf = &args->tf; |
| 358 | u16 data = hwif->INW(IDE_DATA_REG); | 382 | |
| 359 | args->tfRegister[IDE_DATA_OFFSET] = (data) & 0xFF; | 383 | tf->error = err; |
| 360 | args->hobRegister[IDE_DATA_OFFSET] = (data >> 8) & 0xFF; | 384 | tf->status = stat; |
| 361 | } | 385 | |
| 362 | args->tfRegister[IDE_ERROR_OFFSET] = err; | 386 | args->tf_flags |= (IDE_TFLAG_IN_TF|IDE_TFLAG_IN_DEVICE); |
| 363 | /* be sure we're looking at the low order bits */ | 387 | if (args->tf_flags & IDE_TFLAG_LBA48) |
| 364 | hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG); | 388 | args->tf_flags |= IDE_TFLAG_IN_HOB; |
| 365 | args->tfRegister[IDE_NSECTOR_OFFSET] = hwif->INB(IDE_NSECTOR_REG); | 389 | |
| 366 | args->tfRegister[IDE_SECTOR_OFFSET] = hwif->INB(IDE_SECTOR_REG); | 390 | ide_tf_read(drive, args); |
| 367 | args->tfRegister[IDE_LCYL_OFFSET] = hwif->INB(IDE_LCYL_REG); | ||
| 368 | args->tfRegister[IDE_HCYL_OFFSET] = hwif->INB(IDE_HCYL_REG); | ||
| 369 | args->tfRegister[IDE_SELECT_OFFSET] = hwif->INB(IDE_SELECT_REG); | ||
| 370 | args->tfRegister[IDE_STATUS_OFFSET] = stat; | ||
| 371 | |||
| 372 | if (drive->addressing == 1) { | ||
| 373 | hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG); | ||
| 374 | args->hobRegister[IDE_FEATURE_OFFSET] = hwif->INB(IDE_FEATURE_REG); | ||
| 375 | args->hobRegister[IDE_NSECTOR_OFFSET] = hwif->INB(IDE_NSECTOR_REG); | ||
| 376 | args->hobRegister[IDE_SECTOR_OFFSET] = hwif->INB(IDE_SECTOR_REG); | ||
| 377 | args->hobRegister[IDE_LCYL_OFFSET] = hwif->INB(IDE_LCYL_REG); | ||
| 378 | args->hobRegister[IDE_HCYL_OFFSET] = hwif->INB(IDE_HCYL_REG); | ||
| 379 | } | ||
| 380 | } | 391 | } |
| 381 | } else if (blk_pm_request(rq)) { | 392 | } else if (blk_pm_request(rq)) { |
| 382 | struct request_pm_state *pm = rq->data; | 393 | struct request_pm_state *pm = rq->data; |
| @@ -616,28 +627,6 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) | |||
| 616 | } | 627 | } |
| 617 | 628 | ||
| 618 | /** | 629 | /** |
| 619 | * ide_cmd - issue a simple drive command | ||
| 620 | * @drive: drive the command is for | ||
| 621 | * @cmd: command byte | ||
| 622 | * @nsect: sector byte | ||
| 623 | * @handler: handler for the command completion | ||
| 624 | * | ||
| 625 | * Issue a simple drive command with interrupts. | ||
| 626 | * The drive must be selected beforehand. | ||
| 627 | */ | ||
| 628 | |||
| 629 | static void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, | ||
| 630 | ide_handler_t *handler) | ||
| 631 | { | ||
| 632 | ide_hwif_t *hwif = HWIF(drive); | ||
| 633 | if (IDE_CONTROL_REG) | ||
| 634 | hwif->OUTB(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */ | ||
| 635 | SELECT_MASK(drive,0); | ||
| 636 | hwif->OUTB(nsect,IDE_NSECTOR_REG); | ||
| 637 | ide_execute_command(drive, cmd, handler, WAIT_CMD, NULL); | ||
| 638 | } | ||
| 639 | |||
| 640 | /** | ||
| 641 | * drive_cmd_intr - drive command completion interrupt | 630 | * drive_cmd_intr - drive command completion interrupt |
| 642 | * @drive: drive the completion interrupt occurred on | 631 | * @drive: drive the completion interrupt occurred on |
| 643 | * | 632 | * |
| @@ -673,32 +662,26 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) | |||
| 673 | return ide_stopped; | 662 | return ide_stopped; |
| 674 | } | 663 | } |
| 675 | 664 | ||
| 676 | static void ide_init_specify_cmd(ide_drive_t *drive, ide_task_t *task) | 665 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
| 677 | { | 666 | { |
| 678 | task->tfRegister[IDE_NSECTOR_OFFSET] = drive->sect; | 667 | tf->nsect = drive->sect; |
| 679 | task->tfRegister[IDE_SECTOR_OFFSET] = drive->sect; | 668 | tf->lbal = drive->sect; |
| 680 | task->tfRegister[IDE_LCYL_OFFSET] = drive->cyl; | 669 | tf->lbam = drive->cyl; |
| 681 | task->tfRegister[IDE_HCYL_OFFSET] = drive->cyl>>8; | 670 | tf->lbah = drive->cyl >> 8; |
| 682 | task->tfRegister[IDE_SELECT_OFFSET] = ((drive->head-1)|drive->select.all)&0xBF; | 671 | tf->device = ((drive->head - 1) | drive->select.all) & ~ATA_LBA; |
| 683 | task->tfRegister[IDE_COMMAND_OFFSET] = WIN_SPECIFY; | 672 | tf->command = WIN_SPECIFY; |
| 684 | |||
| 685 | task->handler = &set_geometry_intr; | ||
| 686 | } | 673 | } |
| 687 | 674 | ||
| 688 | static void ide_init_restore_cmd(ide_drive_t *drive, ide_task_t *task) | 675 | static void ide_tf_set_restore_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
| 689 | { | 676 | { |
| 690 | task->tfRegister[IDE_NSECTOR_OFFSET] = drive->sect; | 677 | tf->nsect = drive->sect; |
| 691 | task->tfRegister[IDE_COMMAND_OFFSET] = WIN_RESTORE; | 678 | tf->command = WIN_RESTORE; |
| 692 | |||
| 693 | task->handler = &recal_intr; | ||
| 694 | } | 679 | } |
| 695 | 680 | ||
| 696 | static void ide_init_setmult_cmd(ide_drive_t *drive, ide_task_t *task) | 681 | static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
| 697 | { | 682 | { |
| 698 | task->tfRegister[IDE_NSECTOR_OFFSET] = drive->mult_req; | 683 | tf->nsect = drive->mult_req; |
| 699 | task->tfRegister[IDE_COMMAND_OFFSET] = WIN_SETMULT; | 684 | tf->command = WIN_SETMULT; |
| 700 | |||
| 701 | task->handler = &set_multmode_intr; | ||
| 702 | } | 685 | } |
| 703 | 686 | ||
| 704 | static ide_startstop_t ide_disk_special(ide_drive_t *drive) | 687 | static ide_startstop_t ide_disk_special(ide_drive_t *drive) |
| @@ -707,19 +690,19 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) | |||
| 707 | ide_task_t args; | 690 | ide_task_t args; |
| 708 | 691 | ||
| 709 | memset(&args, 0, sizeof(ide_task_t)); | 692 | memset(&args, 0, sizeof(ide_task_t)); |
| 710 | args.command_type = IDE_DRIVE_TASK_NO_DATA; | 693 | args.data_phase = TASKFILE_NO_DATA; |
| 711 | 694 | ||
| 712 | if (s->b.set_geometry) { | 695 | if (s->b.set_geometry) { |
| 713 | s->b.set_geometry = 0; | 696 | s->b.set_geometry = 0; |
| 714 | ide_init_specify_cmd(drive, &args); | 697 | ide_tf_set_specify_cmd(drive, &args.tf); |
| 715 | } else if (s->b.recalibrate) { | 698 | } else if (s->b.recalibrate) { |
| 716 | s->b.recalibrate = 0; | 699 | s->b.recalibrate = 0; |
| 717 | ide_init_restore_cmd(drive, &args); | 700 | ide_tf_set_restore_cmd(drive, &args.tf); |
| 718 | } else if (s->b.set_multmode) { | 701 | } else if (s->b.set_multmode) { |
| 719 | s->b.set_multmode = 0; | 702 | s->b.set_multmode = 0; |
| 720 | if (drive->mult_req > drive->id->max_multsect) | 703 | if (drive->mult_req > drive->id->max_multsect) |
| 721 | drive->mult_req = drive->id->max_multsect; | 704 | drive->mult_req = drive->id->max_multsect; |
| 722 | ide_init_setmult_cmd(drive, &args); | 705 | ide_tf_set_setmult_cmd(drive, &args.tf); |
| 723 | } else if (s->all) { | 706 | } else if (s->all) { |
| 724 | int special = s->all; | 707 | int special = s->all; |
| 725 | s->all = 0; | 708 | s->all = 0; |
| @@ -727,6 +710,9 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) | |||
| 727 | return ide_stopped; | 710 | return ide_stopped; |
| 728 | } | 711 | } |
| 729 | 712 | ||
| 713 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | | ||
| 714 | IDE_TFLAG_CUSTOM_HANDLER; | ||
| 715 | |||
| 730 | do_rw_taskfile(drive, &args); | 716 | do_rw_taskfile(drive, &args); |
| 731 | 717 | ||
| 732 | return ide_started; | 718 | return ide_started; |
| @@ -861,13 +847,17 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
| 861 | struct request *rq) | 847 | struct request *rq) |
| 862 | { | 848 | { |
| 863 | ide_hwif_t *hwif = HWIF(drive); | 849 | ide_hwif_t *hwif = HWIF(drive); |
| 850 | u8 *args = rq->buffer; | ||
| 851 | ide_task_t ltask; | ||
| 852 | struct ide_taskfile *tf = <ask.tf; | ||
| 853 | |||
| 864 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | 854 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
| 865 | ide_task_t *args = rq->special; | 855 | ide_task_t *task = rq->special; |
| 866 | 856 | ||
| 867 | if (!args) | 857 | if (task == NULL) |
| 868 | goto done; | 858 | goto done; |
| 869 | 859 | ||
| 870 | hwif->data_phase = args->data_phase; | 860 | hwif->data_phase = task->data_phase; |
| 871 | 861 | ||
| 872 | switch (hwif->data_phase) { | 862 | switch (hwif->data_phase) { |
| 873 | case TASKFILE_MULTI_OUT: | 863 | case TASKFILE_MULTI_OUT: |
| @@ -880,55 +870,34 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
| 880 | break; | 870 | break; |
| 881 | } | 871 | } |
| 882 | 872 | ||
| 883 | if (args->tf_out_flags.all != 0) | 873 | return do_rw_taskfile(drive, task); |
| 884 | return flagged_taskfile(drive, args); | 874 | } |
| 885 | return do_rw_taskfile(drive, args); | 875 | |
| 886 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASK) { | 876 | if (args == NULL) |
| 887 | u8 *args = rq->buffer; | 877 | goto done; |
| 888 | 878 | ||
| 889 | if (!args) | 879 | memset(<ask, 0, sizeof(ltask)); |
| 890 | goto done; | 880 | if (rq->cmd_type == REQ_TYPE_ATA_CMD) { |
| 891 | #ifdef DEBUG | ||
| 892 | printk("%s: DRIVE_TASK_CMD ", drive->name); | ||
| 893 | printk("cmd=0x%02x ", args[0]); | ||
| 894 | printk("fr=0x%02x ", args[1]); | ||
| 895 | printk("ns=0x%02x ", args[2]); | ||
| 896 | printk("sc=0x%02x ", args[3]); | ||
| 897 | printk("lcyl=0x%02x ", args[4]); | ||
| 898 | printk("hcyl=0x%02x ", args[5]); | ||
| 899 | printk("sel=0x%02x\n", args[6]); | ||
| 900 | #endif | ||
| 901 | hwif->OUTB(args[1], IDE_FEATURE_REG); | ||
| 902 | hwif->OUTB(args[3], IDE_SECTOR_REG); | ||
| 903 | hwif->OUTB(args[4], IDE_LCYL_REG); | ||
| 904 | hwif->OUTB(args[5], IDE_HCYL_REG); | ||
| 905 | hwif->OUTB((args[6] & 0xEF)|drive->select.all, IDE_SELECT_REG); | ||
| 906 | ide_cmd(drive, args[0], args[2], &drive_cmd_intr); | ||
| 907 | return ide_started; | ||
| 908 | } else if (rq->cmd_type == REQ_TYPE_ATA_CMD) { | ||
| 909 | u8 *args = rq->buffer; | ||
| 910 | |||
| 911 | if (!args) | ||
| 912 | goto done; | ||
| 913 | #ifdef DEBUG | 881 | #ifdef DEBUG |
| 914 | printk("%s: DRIVE_CMD ", drive->name); | 882 | printk("%s: DRIVE_CMD\n", drive->name); |
| 915 | printk("cmd=0x%02x ", args[0]); | ||
| 916 | printk("sc=0x%02x ", args[1]); | ||
| 917 | printk("fr=0x%02x ", args[2]); | ||
| 918 | printk("xx=0x%02x\n", args[3]); | ||
| 919 | #endif | 883 | #endif |
| 920 | if (args[0] == WIN_SMART) { | 884 | tf->feature = args[2]; |
| 921 | hwif->OUTB(0x4f, IDE_LCYL_REG); | 885 | if (args[0] == WIN_SMART) { |
| 922 | hwif->OUTB(0xc2, IDE_HCYL_REG); | 886 | tf->nsect = args[3]; |
| 923 | hwif->OUTB(args[2],IDE_FEATURE_REG); | 887 | tf->lbal = args[1]; |
| 924 | hwif->OUTB(args[1],IDE_SECTOR_REG); | 888 | tf->lbam = 0x4f; |
| 925 | ide_cmd(drive, args[0], args[3], &drive_cmd_intr); | 889 | tf->lbah = 0xc2; |
| 926 | return ide_started; | 890 | ltask.tf_flags = IDE_TFLAG_OUT_TF; |
| 927 | } | 891 | } else { |
| 928 | hwif->OUTB(args[2],IDE_FEATURE_REG); | 892 | tf->nsect = args[1]; |
| 929 | ide_cmd(drive, args[0], args[1], &drive_cmd_intr); | 893 | ltask.tf_flags = IDE_TFLAG_OUT_FEATURE | |
| 930 | return ide_started; | 894 | IDE_TFLAG_OUT_NSECT; |
| 895 | } | ||
| 931 | } | 896 | } |
| 897 | tf->command = args[0]; | ||
| 898 | ide_tf_load(drive, <ask); | ||
| 899 | ide_execute_command(drive, args[0], &drive_cmd_intr, WAIT_WORSTCASE, NULL); | ||
| 900 | return ide_started; | ||
| 932 | 901 | ||
| 933 | done: | 902 | done: |
| 934 | /* | 903 | /* |
| @@ -1003,6 +972,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
| 1003 | 972 | ||
| 1004 | /* bail early if we've exceeded max_failures */ | 973 | /* bail early if we've exceeded max_failures */ |
| 1005 | if (drive->max_failures && (drive->failures > drive->max_failures)) { | 974 | if (drive->max_failures && (drive->failures > drive->max_failures)) { |
| 975 | rq->cmd_flags |= REQ_FAILED; | ||
| 1006 | goto kill_rq; | 976 | goto kill_rq; |
| 1007 | } | 977 | } |
| 1008 | 978 | ||
| @@ -1035,7 +1005,6 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
| 1035 | ide_config_drive_speed(drive, drive->desired_speed); | 1005 | ide_config_drive_speed(drive, drive->desired_speed); |
| 1036 | 1006 | ||
| 1037 | if (rq->cmd_type == REQ_TYPE_ATA_CMD || | 1007 | if (rq->cmd_type == REQ_TYPE_ATA_CMD || |
| 1038 | rq->cmd_type == REQ_TYPE_ATA_TASK || | ||
| 1039 | rq->cmd_type == REQ_TYPE_ATA_TASKFILE) | 1008 | rq->cmd_type == REQ_TYPE_ATA_TASKFILE) |
| 1040 | return execute_drive_cmd(drive, rq); | 1009 | return execute_drive_cmd(drive, rq); |
| 1041 | else if (blk_pm_request(rq)) { | 1010 | else if (blk_pm_request(rq)) { |
| @@ -1247,8 +1216,12 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
| 1247 | if (hwgroup->hwif->sharing_irq && | 1216 | if (hwgroup->hwif->sharing_irq && |
| 1248 | hwif != hwgroup->hwif && | 1217 | hwif != hwgroup->hwif && |
| 1249 | hwif->io_ports[IDE_CONTROL_OFFSET]) { | 1218 | hwif->io_ports[IDE_CONTROL_OFFSET]) { |
| 1250 | /* set nIEN for previous hwif */ | 1219 | /* |
| 1251 | SELECT_INTERRUPT(drive); | 1220 | * set nIEN for previous hwif, drives in the |
| 1221 | * quirk_list may not like intr setups/cleanups | ||
| 1222 | */ | ||
| 1223 | if (drive->quirk_list != 1) | ||
| 1224 | hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); | ||
| 1252 | } | 1225 | } |
| 1253 | hwgroup->hwif = hwif; | 1226 | hwgroup->hwif = hwif; |
| 1254 | hwgroup->drive = drive; | 1227 | hwgroup->drive = drive; |
| @@ -1454,12 +1427,8 @@ void ide_timer_expiry (unsigned long data) | |||
| 1454 | */ | 1427 | */ |
| 1455 | spin_unlock(&ide_lock); | 1428 | spin_unlock(&ide_lock); |
| 1456 | hwif = HWIF(drive); | 1429 | hwif = HWIF(drive); |
| 1457 | #if DISABLE_IRQ_NOSYNC | ||
| 1458 | disable_irq_nosync(hwif->irq); | ||
| 1459 | #else | ||
| 1460 | /* disable_irq_nosync ?? */ | 1430 | /* disable_irq_nosync ?? */ |
| 1461 | disable_irq(hwif->irq); | 1431 | disable_irq(hwif->irq); |
| 1462 | #endif /* DISABLE_IRQ_NOSYNC */ | ||
| 1463 | /* local CPU only, | 1432 | /* local CPU only, |
| 1464 | * as if we were handling an interrupt */ | 1433 | * as if we were handling an interrupt */ |
| 1465 | local_irq_disable(); | 1434 | local_irq_disable(); |
| @@ -1785,3 +1754,19 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio | |||
| 1785 | } | 1754 | } |
| 1786 | 1755 | ||
| 1787 | EXPORT_SYMBOL(ide_do_drive_cmd); | 1756 | EXPORT_SYMBOL(ide_do_drive_cmd); |
| 1757 | |||
| 1758 | void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma) | ||
| 1759 | { | ||
| 1760 | ide_task_t task; | ||
| 1761 | |||
| 1762 | memset(&task, 0, sizeof(task)); | ||
| 1763 | task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | | ||
| 1764 | IDE_TFLAG_OUT_FEATURE | tf_flags; | ||
| 1765 | task.tf.feature = dma; /* Use PIO/DMA */ | ||
| 1766 | task.tf.lbam = bcount & 0xff; | ||
| 1767 | task.tf.lbah = (bcount >> 8) & 0xff; | ||
| 1768 | |||
| 1769 | ide_tf_load(drive, &task); | ||
| 1770 | } | ||
| 1771 | |||
| 1772 | EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load); | ||
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index bb9693dabe41..c97c0719ddf1 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
| @@ -158,14 +158,6 @@ void default_hwif_mmiops (ide_hwif_t *hwif) | |||
| 158 | 158 | ||
| 159 | EXPORT_SYMBOL(default_hwif_mmiops); | 159 | EXPORT_SYMBOL(default_hwif_mmiops); |
| 160 | 160 | ||
| 161 | u32 ide_read_24 (ide_drive_t *drive) | ||
| 162 | { | ||
| 163 | u8 hcyl = HWIF(drive)->INB(IDE_HCYL_REG); | ||
| 164 | u8 lcyl = HWIF(drive)->INB(IDE_LCYL_REG); | ||
| 165 | u8 sect = HWIF(drive)->INB(IDE_SECTOR_REG); | ||
| 166 | return (hcyl<<16)|(lcyl<<8)|sect; | ||
| 167 | } | ||
| 168 | |||
| 169 | void SELECT_DRIVE (ide_drive_t *drive) | 161 | void SELECT_DRIVE (ide_drive_t *drive) |
| 170 | { | 162 | { |
| 171 | if (HWIF(drive)->selectproc) | 163 | if (HWIF(drive)->selectproc) |
| @@ -175,26 +167,12 @@ void SELECT_DRIVE (ide_drive_t *drive) | |||
| 175 | 167 | ||
| 176 | EXPORT_SYMBOL(SELECT_DRIVE); | 168 | EXPORT_SYMBOL(SELECT_DRIVE); |
| 177 | 169 | ||
| 178 | void SELECT_INTERRUPT (ide_drive_t *drive) | ||
| 179 | { | ||
| 180 | if (HWIF(drive)->intrproc) | ||
| 181 | HWIF(drive)->intrproc(drive); | ||
| 182 | else | ||
| 183 | HWIF(drive)->OUTB(drive->ctl|2, IDE_CONTROL_REG); | ||
| 184 | } | ||
| 185 | |||
| 186 | void SELECT_MASK (ide_drive_t *drive, int mask) | 170 | void SELECT_MASK (ide_drive_t *drive, int mask) |
| 187 | { | 171 | { |
| 188 | if (HWIF(drive)->maskproc) | 172 | if (HWIF(drive)->maskproc) |
| 189 | HWIF(drive)->maskproc(drive, mask); | 173 | HWIF(drive)->maskproc(drive, mask); |
| 190 | } | 174 | } |
| 191 | 175 | ||
| 192 | void QUIRK_LIST (ide_drive_t *drive) | ||
| 193 | { | ||
| 194 | if (HWIF(drive)->quirkproc) | ||
| 195 | drive->quirk_list = HWIF(drive)->quirkproc(drive); | ||
| 196 | } | ||
| 197 | |||
| 198 | /* | 176 | /* |
| 199 | * Some localbus EIDE interfaces require a special access sequence | 177 | * Some localbus EIDE interfaces require a special access sequence |
| 200 | * when using 32-bit I/O instructions to transfer data. We call this | 178 | * when using 32-bit I/O instructions to transfer data. We call this |
| @@ -449,7 +427,6 @@ int drive_is_ready (ide_drive_t *drive) | |||
| 449 | udelay(1); | 427 | udelay(1); |
| 450 | #endif | 428 | #endif |
| 451 | 429 | ||
| 452 | #ifdef CONFIG_IDEPCI_SHARE_IRQ | ||
| 453 | /* | 430 | /* |
| 454 | * We do a passive status test under shared PCI interrupts on | 431 | * We do a passive status test under shared PCI interrupts on |
| 455 | * cards that truly share the ATA side interrupt, but may also share | 432 | * cards that truly share the ATA side interrupt, but may also share |
| @@ -459,7 +436,6 @@ int drive_is_ready (ide_drive_t *drive) | |||
| 459 | if (IDE_CONTROL_REG) | 436 | if (IDE_CONTROL_REG) |
| 460 | stat = hwif->INB(IDE_ALTSTATUS_REG); | 437 | stat = hwif->INB(IDE_ALTSTATUS_REG); |
| 461 | else | 438 | else |
| 462 | #endif /* CONFIG_IDEPCI_SHARE_IRQ */ | ||
| 463 | /* Note: this may clear a pending IRQ!! */ | 439 | /* Note: this may clear a pending IRQ!! */ |
| 464 | stat = hwif->INB(IDE_STATUS_REG); | 440 | stat = hwif->INB(IDE_STATUS_REG); |
| 465 | 441 | ||
| @@ -642,9 +618,9 @@ no_80w: | |||
| 642 | 618 | ||
| 643 | int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) | 619 | int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) |
| 644 | { | 620 | { |
| 645 | if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && | 621 | if (args->tf.command == WIN_SETFEATURES && |
| 646 | (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) && | 622 | args->tf.lbal > XFER_UDMA_2 && |
| 647 | (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) { | 623 | args->tf.feature == SETFEATURES_XFER) { |
| 648 | if (eighty_ninty_three(drive) == 0) { | 624 | if (eighty_ninty_three(drive) == 0) { |
| 649 | printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " | 625 | printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " |
| 650 | "be set\n", drive->name); | 626 | "be set\n", drive->name); |
| @@ -662,9 +638,9 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) | |||
| 662 | */ | 638 | */ |
| 663 | int set_transfer (ide_drive_t *drive, ide_task_t *args) | 639 | int set_transfer (ide_drive_t *drive, ide_task_t *args) |
| 664 | { | 640 | { |
| 665 | if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && | 641 | if (args->tf.command == WIN_SETFEATURES && |
| 666 | (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) && | 642 | args->tf.lbal >= XFER_SW_DMA_0 && |
| 667 | (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) && | 643 | args->tf.feature == SETFEATURES_XFER && |
| 668 | (drive->id->dma_ultra || | 644 | (drive->id->dma_ultra || |
| 669 | drive->id->dma_mword || | 645 | drive->id->dma_mword || |
| 670 | drive->id->dma_1word)) | 646 | drive->id->dma_1word)) |
| @@ -902,8 +878,9 @@ EXPORT_SYMBOL(ide_set_handler); | |||
| 902 | * handler and IRQ setup do not race. All IDE command kick off | 878 | * handler and IRQ setup do not race. All IDE command kick off |
| 903 | * should go via this function or do equivalent locking. | 879 | * should go via this function or do equivalent locking. |
| 904 | */ | 880 | */ |
| 905 | 881 | ||
| 906 | void ide_execute_command(ide_drive_t *drive, task_ioreg_t cmd, ide_handler_t *handler, unsigned timeout, ide_expiry_t *expiry) | 882 | void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, |
| 883 | unsigned timeout, ide_expiry_t *expiry) | ||
| 907 | { | 884 | { |
| 908 | unsigned long flags; | 885 | unsigned long flags; |
| 909 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | 886 | ide_hwgroup_t *hwgroup = HWGROUP(drive); |
| @@ -1051,8 +1028,7 @@ static void ide_disk_pre_reset(ide_drive_t *drive) | |||
| 1051 | drive->special.all = 0; | 1028 | drive->special.all = 0; |
| 1052 | drive->special.b.set_geometry = legacy; | 1029 | drive->special.b.set_geometry = legacy; |
| 1053 | drive->special.b.recalibrate = legacy; | 1030 | drive->special.b.recalibrate = legacy; |
| 1054 | if (OK_TO_RESET_CONTROLLER) | 1031 | drive->mult_count = 0; |
| 1055 | drive->mult_count = 0; | ||
| 1056 | if (!drive->keep_settings && !drive->using_dma) | 1032 | if (!drive->keep_settings && !drive->using_dma) |
| 1057 | drive->mult_req = 0; | 1033 | drive->mult_req = 0; |
| 1058 | if (drive->mult_req != drive->mult_count) | 1034 | if (drive->mult_req != drive->mult_count) |
| @@ -1137,7 +1113,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
| 1137 | for (unit = 0; unit < MAX_DRIVES; ++unit) | 1113 | for (unit = 0; unit < MAX_DRIVES; ++unit) |
| 1138 | pre_reset(&hwif->drives[unit]); | 1114 | pre_reset(&hwif->drives[unit]); |
| 1139 | 1115 | ||
| 1140 | #if OK_TO_RESET_CONTROLLER | ||
| 1141 | if (!IDE_CONTROL_REG) { | 1116 | if (!IDE_CONTROL_REG) { |
| 1142 | spin_unlock_irqrestore(&ide_lock, flags); | 1117 | spin_unlock_irqrestore(&ide_lock, flags); |
| 1143 | return ide_stopped; | 1118 | return ide_stopped; |
| @@ -1174,11 +1149,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
| 1174 | * state when the disks are reset this way. At least, the Winbond | 1149 | * state when the disks are reset this way. At least, the Winbond |
| 1175 | * 553 documentation says that | 1150 | * 553 documentation says that |
| 1176 | */ | 1151 | */ |
| 1177 | if (hwif->resetproc != NULL) { | 1152 | if (hwif->resetproc) |
| 1178 | hwif->resetproc(drive); | 1153 | hwif->resetproc(drive); |
| 1179 | } | ||
| 1180 | |||
| 1181 | #endif /* OK_TO_RESET_CONTROLLER */ | ||
| 1182 | 1154 | ||
| 1183 | spin_unlock_irqrestore(&ide_lock, flags); | 1155 | spin_unlock_irqrestore(&ide_lock, flags); |
| 1184 | return ide_started; | 1156 | return ide_started; |
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 062d3bcb2471..a3bd8e8ed6b0 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
| @@ -441,6 +441,12 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) | |||
| 441 | * case could happen iff the transfer mode has already been set on | 441 | * case could happen iff the transfer mode has already been set on |
| 442 | * the device by ide-proc.c::set_xfer_rate()). | 442 | * the device by ide-proc.c::set_xfer_rate()). |
| 443 | */ | 443 | */ |
| 444 | if (rate < XFER_PIO_0) { | ||
| 445 | if (hwif->host_flags & IDE_HFLAG_ABUSE_SET_DMA_MODE) | ||
| 446 | return ide_set_dma_mode(drive, rate); | ||
| 447 | else | ||
| 448 | return ide_config_drive_speed(drive, rate); | ||
| 449 | } | ||
| 444 | 450 | ||
| 445 | return ide_set_dma_mode(drive, rate); | 451 | return ide_set_dma_mode(drive, rate); |
| 446 | } | 452 | } |
| @@ -458,8 +464,7 @@ static void ide_dump_opcode(ide_drive_t *drive) | |||
| 458 | spin_unlock(&ide_lock); | 464 | spin_unlock(&ide_lock); |
| 459 | if (!rq) | 465 | if (!rq) |
| 460 | return; | 466 | return; |
| 461 | if (rq->cmd_type == REQ_TYPE_ATA_CMD || | 467 | if (rq->cmd_type == REQ_TYPE_ATA_CMD) { |
| 462 | rq->cmd_type == REQ_TYPE_ATA_TASK) { | ||
| 463 | char *args = rq->buffer; | 468 | char *args = rq->buffer; |
| 464 | if (args) { | 469 | if (args) { |
| 465 | opcode = args[0]; | 470 | opcode = args[0]; |
| @@ -468,8 +473,7 @@ static void ide_dump_opcode(ide_drive_t *drive) | |||
| 468 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | 473 | } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
| 469 | ide_task_t *args = rq->special; | 474 | ide_task_t *args = rq->special; |
| 470 | if (args) { | 475 | if (args) { |
| 471 | task_struct_t *tf = (task_struct_t *) args->tfRegister; | 476 | opcode = args->tf.command; |
| 472 | opcode = tf->command; | ||
| 473 | found = 1; | 477 | found = 1; |
| 474 | } | 478 | } |
| 475 | } | 479 | } |
| @@ -481,141 +485,118 @@ static void ide_dump_opcode(ide_drive_t *drive) | |||
| 481 | printk("0x%02x\n", opcode); | 485 | printk("0x%02x\n", opcode); |
| 482 | } | 486 | } |
| 483 | 487 | ||
| 484 | static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) | 488 | u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48) |
| 485 | { | 489 | { |
| 486 | ide_hwif_t *hwif = HWIF(drive); | 490 | u32 high, low; |
| 487 | unsigned long flags; | ||
| 488 | u8 err = 0; | ||
| 489 | 491 | ||
| 490 | local_irq_save(flags); | 492 | if (lba48) |
| 491 | printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); | 493 | high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | |
| 492 | if (stat & BUSY_STAT) | 494 | tf->hob_lbal; |
| 493 | printk("Busy "); | 495 | else |
| 494 | else { | 496 | high = tf->device & 0xf; |
| 495 | if (stat & READY_STAT) printk("DriveReady "); | 497 | low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; |
| 496 | if (stat & WRERR_STAT) printk("DeviceFault "); | 498 | |
| 497 | if (stat & SEEK_STAT) printk("SeekComplete "); | 499 | return ((u64)high << 24) | low; |
| 498 | if (stat & DRQ_STAT) printk("DataRequest "); | 500 | } |
| 499 | if (stat & ECC_STAT) printk("CorrectedError "); | 501 | EXPORT_SYMBOL_GPL(ide_get_lba_addr); |
| 500 | if (stat & INDEX_STAT) printk("Index "); | 502 | |
| 501 | if (stat & ERR_STAT) printk("Error "); | 503 | static void ide_dump_sector(ide_drive_t *drive) |
| 504 | { | ||
| 505 | ide_task_t task; | ||
| 506 | struct ide_taskfile *tf = &task.tf; | ||
| 507 | int lba48 = (drive->addressing == 1) ? 1 : 0; | ||
| 508 | |||
| 509 | memset(&task, 0, sizeof(task)); | ||
| 510 | if (lba48) | ||
| 511 | task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA | | ||
| 512 | IDE_TFLAG_LBA48; | ||
| 513 | else | ||
| 514 | task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE; | ||
| 515 | |||
| 516 | ide_tf_read(drive, &task); | ||
| 517 | |||
| 518 | if (lba48 || (tf->device & ATA_LBA)) | ||
| 519 | printk(", LBAsect=%llu", | ||
| 520 | (unsigned long long)ide_get_lba_addr(tf, lba48)); | ||
| 521 | else | ||
| 522 | printk(", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam, | ||
| 523 | tf->device & 0xf, tf->lbal); | ||
| 524 | } | ||
| 525 | |||
| 526 | static void ide_dump_ata_error(ide_drive_t *drive, u8 err) | ||
| 527 | { | ||
| 528 | printk("{ "); | ||
| 529 | if (err & ABRT_ERR) printk("DriveStatusError "); | ||
| 530 | if (err & ICRC_ERR) | ||
| 531 | printk((err & ABRT_ERR) ? "BadCRC " : "BadSector "); | ||
| 532 | if (err & ECC_ERR) printk("UncorrectableError "); | ||
| 533 | if (err & ID_ERR) printk("SectorIdNotFound "); | ||
| 534 | if (err & TRK0_ERR) printk("TrackZeroNotFound "); | ||
| 535 | if (err & MARK_ERR) printk("AddrMarkNotFound "); | ||
| 536 | printk("}"); | ||
| 537 | if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || | ||
| 538 | (err & (ECC_ERR|ID_ERR|MARK_ERR))) { | ||
| 539 | ide_dump_sector(drive); | ||
| 540 | if (HWGROUP(drive) && HWGROUP(drive)->rq) | ||
| 541 | printk(", sector=%llu", | ||
| 542 | (unsigned long long)HWGROUP(drive)->rq->sector); | ||
| 502 | } | 543 | } |
| 544 | printk("\n"); | ||
| 545 | } | ||
| 546 | |||
| 547 | static void ide_dump_atapi_error(ide_drive_t *drive, u8 err) | ||
| 548 | { | ||
| 549 | printk("{ "); | ||
| 550 | if (err & ILI_ERR) printk("IllegalLengthIndication "); | ||
| 551 | if (err & EOM_ERR) printk("EndOfMedia "); | ||
| 552 | if (err & ABRT_ERR) printk("AbortedCommand "); | ||
| 553 | if (err & MCR_ERR) printk("MediaChangeRequested "); | ||
| 554 | if (err & LFS_ERR) printk("LastFailedSense=0x%02x ", | ||
| 555 | (err & LFS_ERR) >> 4); | ||
| 503 | printk("}\n"); | 556 | printk("}\n"); |
| 504 | if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { | ||
| 505 | err = hwif->INB(IDE_ERROR_REG); | ||
| 506 | printk("%s: %s: error=0x%02x { ", drive->name, msg, err); | ||
| 507 | if (err & ABRT_ERR) printk("DriveStatusError "); | ||
| 508 | if (err & ICRC_ERR) | ||
| 509 | printk((err & ABRT_ERR) ? "BadCRC " : "BadSector "); | ||
| 510 | if (err & ECC_ERR) printk("UncorrectableError "); | ||
| 511 | if (err & ID_ERR) printk("SectorIdNotFound "); | ||
| 512 | if (err & TRK0_ERR) printk("TrackZeroNotFound "); | ||
| 513 | if (err & MARK_ERR) printk("AddrMarkNotFound "); | ||
| 514 | printk("}"); | ||
| 515 | if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || | ||
| 516 | (err & (ECC_ERR|ID_ERR|MARK_ERR))) { | ||
| 517 | if (drive->addressing == 1) { | ||
| 518 | __u64 sectors = 0; | ||
| 519 | u32 low = 0, high = 0; | ||
| 520 | hwif->OUTB(drive->ctl&~0x80, IDE_CONTROL_REG); | ||
| 521 | low = ide_read_24(drive); | ||
| 522 | hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG); | ||
| 523 | high = ide_read_24(drive); | ||
| 524 | sectors = ((__u64)high << 24) | low; | ||
| 525 | printk(", LBAsect=%llu, high=%d, low=%d", | ||
| 526 | (unsigned long long) sectors, | ||
| 527 | high, low); | ||
| 528 | } else { | ||
| 529 | u8 cur = hwif->INB(IDE_SELECT_REG); | ||
| 530 | if (cur & 0x40) { /* using LBA? */ | ||
| 531 | printk(", LBAsect=%ld", (unsigned long) | ||
| 532 | ((cur&0xf)<<24) | ||
| 533 | |(hwif->INB(IDE_HCYL_REG)<<16) | ||
| 534 | |(hwif->INB(IDE_LCYL_REG)<<8) | ||
| 535 | | hwif->INB(IDE_SECTOR_REG)); | ||
| 536 | } else { | ||
| 537 | printk(", CHS=%d/%d/%d", | ||
| 538 | (hwif->INB(IDE_HCYL_REG)<<8) + | ||
| 539 | hwif->INB(IDE_LCYL_REG), | ||
| 540 | cur & 0xf, | ||
| 541 | hwif->INB(IDE_SECTOR_REG)); | ||
| 542 | } | ||
| 543 | } | ||
| 544 | if (HWGROUP(drive) && HWGROUP(drive)->rq) | ||
| 545 | printk(", sector=%llu", | ||
| 546 | (unsigned long long)HWGROUP(drive)->rq->sector); | ||
| 547 | } | ||
| 548 | printk("\n"); | ||
| 549 | } | ||
| 550 | ide_dump_opcode(drive); | ||
| 551 | local_irq_restore(flags); | ||
| 552 | return err; | ||
| 553 | } | 557 | } |
| 554 | 558 | ||
| 555 | /** | 559 | /** |
| 556 | * ide_dump_atapi_status - print human readable atapi status | 560 | * ide_dump_status - translate ATA/ATAPI error |
| 557 | * @drive: drive that status applies to | 561 | * @drive: drive that status applies to |
| 558 | * @msg: text message to print | 562 | * @msg: text message to print |
| 559 | * @stat: status byte to decode | 563 | * @stat: status byte to decode |
| 560 | * | 564 | * |
| 561 | * Error reporting, in human readable form (luxurious, but a memory hog). | 565 | * Error reporting, in human readable form (luxurious, but a memory hog). |
| 566 | * Combines the drive name, message and status byte to provide a | ||
| 567 | * user understandable explanation of the device error. | ||
| 562 | */ | 568 | */ |
| 563 | 569 | ||
| 564 | static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat) | 570 | u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) |
| 565 | { | 571 | { |
| 566 | unsigned long flags; | 572 | unsigned long flags; |
| 573 | u8 err = 0; | ||
| 567 | 574 | ||
| 568 | atapi_status_t status; | ||
| 569 | atapi_error_t error; | ||
| 570 | |||
| 571 | status.all = stat; | ||
| 572 | error.all = 0; | ||
| 573 | local_irq_save(flags); | 575 | local_irq_save(flags); |
| 574 | printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); | 576 | printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); |
| 575 | if (status.b.bsy) | 577 | if (stat & BUSY_STAT) |
| 576 | printk("Busy "); | 578 | printk("Busy "); |
| 577 | else { | 579 | else { |
| 578 | if (status.b.drdy) printk("DriveReady "); | 580 | if (stat & READY_STAT) printk("DriveReady "); |
| 579 | if (status.b.df) printk("DeviceFault "); | 581 | if (stat & WRERR_STAT) printk("DeviceFault "); |
| 580 | if (status.b.dsc) printk("SeekComplete "); | 582 | if (stat & SEEK_STAT) printk("SeekComplete "); |
| 581 | if (status.b.drq) printk("DataRequest "); | 583 | if (stat & DRQ_STAT) printk("DataRequest "); |
| 582 | if (status.b.corr) printk("CorrectedError "); | 584 | if (stat & ECC_STAT) printk("CorrectedError "); |
| 583 | if (status.b.idx) printk("Index "); | 585 | if (stat & INDEX_STAT) printk("Index "); |
| 584 | if (status.b.check) printk("Error "); | 586 | if (stat & ERR_STAT) printk("Error "); |
| 585 | } | 587 | } |
| 586 | printk("}\n"); | 588 | printk("}\n"); |
| 587 | if (status.b.check && !status.b.bsy) { | 589 | if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { |
| 588 | error.all = HWIF(drive)->INB(IDE_ERROR_REG); | 590 | err = drive->hwif->INB(IDE_ERROR_REG); |
| 589 | printk("%s: %s: error=0x%02x { ", drive->name, msg, error.all); | 591 | printk("%s: %s: error=0x%02x ", drive->name, msg, err); |
| 590 | if (error.b.ili) printk("IllegalLengthIndication "); | 592 | if (drive->media == ide_disk) |
| 591 | if (error.b.eom) printk("EndOfMedia "); | 593 | ide_dump_ata_error(drive, err); |
| 592 | if (error.b.abrt) printk("AbortedCommand "); | 594 | else |
| 593 | if (error.b.mcr) printk("MediaChangeRequested "); | 595 | ide_dump_atapi_error(drive, err); |
| 594 | if (error.b.sense_key) printk("LastFailedSense=0x%02x ", | ||
| 595 | error.b.sense_key); | ||
| 596 | printk("}\n"); | ||
| 597 | } | 596 | } |
| 598 | ide_dump_opcode(drive); | 597 | ide_dump_opcode(drive); |
| 599 | local_irq_restore(flags); | 598 | local_irq_restore(flags); |
| 600 | return error.all; | 599 | return err; |
| 601 | } | ||
| 602 | |||
| 603 | /** | ||
| 604 | * ide_dump_status - translate ATA/ATAPI error | ||
| 605 | * @drive: drive the error occured on | ||
| 606 | * @msg: information string | ||
| 607 | * @stat: status byte | ||
| 608 | * | ||
| 609 | * Error reporting, in human readable form (luxurious, but a memory hog). | ||
| 610 | * Combines the drive name, message and status byte to provide a | ||
| 611 | * user understandable explanation of the device error. | ||
| 612 | */ | ||
| 613 | |||
| 614 | u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) | ||
| 615 | { | ||
| 616 | if (drive->media == ide_disk) | ||
| 617 | return ide_dump_ata_status(drive, msg, stat); | ||
| 618 | return ide_dump_atapi_status(drive, msg, stat); | ||
| 619 | } | 600 | } |
| 620 | 601 | ||
| 621 | EXPORT_SYMBOL(ide_dump_status); | 602 | EXPORT_SYMBOL(ide_dump_status); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 0cb3d2bb3ab9..0379d1f697cf 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
| @@ -95,10 +95,10 @@ static void ide_disk_init_mult_count(ide_drive_t *drive) | |||
| 95 | #ifdef CONFIG_IDEDISK_MULTI_MODE | 95 | #ifdef CONFIG_IDEDISK_MULTI_MODE |
| 96 | id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0; | 96 | id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0; |
| 97 | id->multsect_valid = id->multsect ? 1 : 0; | 97 | id->multsect_valid = id->multsect ? 1 : 0; |
| 98 | drive->mult_req = id->multsect_valid ? id->max_multsect : INITIAL_MULT_COUNT; | 98 | drive->mult_req = id->multsect_valid ? id->max_multsect : 0; |
| 99 | drive->special.b.set_multmode = drive->mult_req ? 1 : 0; | 99 | drive->special.b.set_multmode = drive->mult_req ? 1 : 0; |
| 100 | #else /* original, pre IDE-NFG, per request of AC */ | 100 | #else /* original, pre IDE-NFG, per request of AC */ |
| 101 | drive->mult_req = INITIAL_MULT_COUNT; | 101 | drive->mult_req = 0; |
| 102 | if (drive->mult_req > id->max_multsect) | 102 | if (drive->mult_req > id->max_multsect) |
| 103 | drive->mult_req = id->max_multsect; | 103 | drive->mult_req = id->max_multsect; |
| 104 | if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect)) | 104 | if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect)) |
| @@ -234,7 +234,10 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
| 234 | 234 | ||
| 235 | drive->media = ide_disk; | 235 | drive->media = ide_disk; |
| 236 | printk("%s DISK drive\n", (id->config == 0x848a) ? "CFA" : "ATA" ); | 236 | printk("%s DISK drive\n", (id->config == 0x848a) ? "CFA" : "ATA" ); |
| 237 | QUIRK_LIST(drive); | 237 | |
| 238 | if (hwif->quirkproc) | ||
| 239 | drive->quirk_list = hwif->quirkproc(drive); | ||
| 240 | |||
| 238 | return; | 241 | return; |
| 239 | 242 | ||
| 240 | err_misc: | 243 | err_misc: |
| @@ -830,16 +833,8 @@ static void probe_hwif(ide_hwif_t *hwif) | |||
| 830 | 833 | ||
| 831 | drive->nice1 = 1; | 834 | drive->nice1 = 1; |
| 832 | 835 | ||
| 833 | if (hwif->ide_dma_on) { | 836 | if (hwif->ide_dma_on) |
| 834 | /* | ||
| 835 | * Force DMAing for the beginning of the check. | ||
| 836 | * Some chipsets appear to do interesting | ||
| 837 | * things, if not checked and cleared. | ||
| 838 | * PARANOIA!!! | ||
| 839 | */ | ||
| 840 | hwif->dma_off_quietly(drive); | ||
| 841 | ide_set_dma(drive); | 837 | ide_set_dma(drive); |
| 842 | } | ||
| 843 | } | 838 | } |
| 844 | } | 839 | } |
| 845 | 840 | ||
| @@ -968,11 +963,6 @@ static int ide_init_queue(ide_drive_t *drive) | |||
| 968 | * Much of the code is for correctly detecting/handling irq sharing | 963 | * Much of the code is for correctly detecting/handling irq sharing |
| 969 | * and irq serialization situations. This is somewhat complex because | 964 | * and irq serialization situations. This is somewhat complex because |
| 970 | * it handles static as well as dynamic (PCMCIA) IDE interfaces. | 965 | * it handles static as well as dynamic (PCMCIA) IDE interfaces. |
| 971 | * | ||
| 972 | * The IRQF_DISABLED in sa_flags means ide_intr() is always entered with | ||
| 973 | * interrupts completely disabled. This can be bad for interrupt latency, | ||
| 974 | * but anything else has led to problems on some machines. We re-enable | ||
| 975 | * interrupts as much as we can safely do in most places. | ||
| 976 | */ | 966 | */ |
| 977 | static int init_irq (ide_hwif_t *hwif) | 967 | static int init_irq (ide_hwif_t *hwif) |
| 978 | { | 968 | { |
| @@ -1055,17 +1045,13 @@ static int init_irq (ide_hwif_t *hwif) | |||
| 1055 | * Allocate the irq, if not already obtained for another hwif | 1045 | * Allocate the irq, if not already obtained for another hwif |
| 1056 | */ | 1046 | */ |
| 1057 | if (!match || match->irq != hwif->irq) { | 1047 | if (!match || match->irq != hwif->irq) { |
| 1058 | int sa = IRQF_DISABLED; | 1048 | int sa = 0; |
| 1059 | #if defined(__mc68000__) || defined(CONFIG_APUS) | 1049 | #if defined(__mc68000__) || defined(CONFIG_APUS) |
| 1060 | sa = IRQF_SHARED; | 1050 | sa = IRQF_SHARED; |
| 1061 | #endif /* __mc68000__ || CONFIG_APUS */ | 1051 | #endif /* __mc68000__ || CONFIG_APUS */ |
| 1062 | 1052 | ||
| 1063 | if (IDE_CHIPSET_IS_PCI(hwif->chipset)) { | 1053 | if (IDE_CHIPSET_IS_PCI(hwif->chipset)) |
| 1064 | sa = IRQF_SHARED; | 1054 | sa = IRQF_SHARED; |
| 1065 | #ifndef CONFIG_IDEPCI_SHARE_IRQ | ||
| 1066 | sa |= IRQF_DISABLED; | ||
| 1067 | #endif /* CONFIG_IDEPCI_SHARE_IRQ */ | ||
| 1068 | } | ||
| 1069 | 1055 | ||
| 1070 | if (hwif->io_ports[IDE_CONTROL_OFFSET]) | 1056 | if (hwif->io_ports[IDE_CONTROL_OFFSET]) |
| 1071 | /* clear nIEN */ | 1057 | /* clear nIEN */ |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1495792d7917..3cbca3f4628a 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
| @@ -615,16 +615,6 @@ typedef struct os_dat_s { | |||
| 615 | /*************************** End of tunable parameters ***********************/ | 615 | /*************************** End of tunable parameters ***********************/ |
| 616 | 616 | ||
| 617 | /* | 617 | /* |
| 618 | * Debugging/Performance analysis | ||
| 619 | * | ||
| 620 | * I/O trace support | ||
| 621 | */ | ||
| 622 | #define USE_IOTRACE 0 | ||
| 623 | #if USE_IOTRACE | ||
| 624 | #define IO_IDETAPE_FIFO 500 | ||
| 625 | #endif | ||
| 626 | |||
| 627 | /* | ||
| 628 | * Read/Write error simulation | 618 | * Read/Write error simulation |
| 629 | */ | 619 | */ |
| 630 | #define SIMULATE_ERRORS 0 | 620 | #define SIMULATE_ERRORS 0 |
| @@ -1818,9 +1808,8 @@ static ide_startstop_t idetape_retry_pc (ide_drive_t *drive) | |||
| 1818 | idetape_tape_t *tape = drive->driver_data; | 1808 | idetape_tape_t *tape = drive->driver_data; |
| 1819 | idetape_pc_t *pc; | 1809 | idetape_pc_t *pc; |
| 1820 | struct request *rq; | 1810 | struct request *rq; |
| 1821 | atapi_error_t error; | ||
| 1822 | 1811 | ||
| 1823 | error.all = HWIF(drive)->INB(IDE_ERROR_REG); | 1812 | (void)drive->hwif->INB(IDE_ERROR_REG); |
| 1824 | pc = idetape_next_pc_storage(drive); | 1813 | pc = idetape_next_pc_storage(drive); |
| 1825 | rq = idetape_next_rq_storage(drive); | 1814 | rq = idetape_next_rq_storage(drive); |
| 1826 | idetape_create_request_sense_cmd(pc); | 1815 | idetape_create_request_sense_cmd(pc); |
| @@ -1858,15 +1847,13 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
| 1858 | { | 1847 | { |
| 1859 | ide_hwif_t *hwif = drive->hwif; | 1848 | ide_hwif_t *hwif = drive->hwif; |
| 1860 | idetape_tape_t *tape = drive->driver_data; | 1849 | idetape_tape_t *tape = drive->driver_data; |
| 1861 | atapi_status_t status; | ||
| 1862 | atapi_bcount_t bcount; | ||
| 1863 | atapi_ireason_t ireason; | ||
| 1864 | idetape_pc_t *pc = tape->pc; | 1850 | idetape_pc_t *pc = tape->pc; |
| 1865 | |||
| 1866 | unsigned int temp; | 1851 | unsigned int temp; |
| 1867 | #if SIMULATE_ERRORS | 1852 | #if SIMULATE_ERRORS |
| 1868 | static int error_sim_count = 0; | 1853 | static int error_sim_count = 0; |
| 1869 | #endif | 1854 | #endif |
| 1855 | u16 bcount; | ||
| 1856 | u8 stat, ireason; | ||
| 1870 | 1857 | ||
| 1871 | #if IDETAPE_DEBUG_LOG | 1858 | #if IDETAPE_DEBUG_LOG |
| 1872 | if (tape->debug_level >= 4) | 1859 | if (tape->debug_level >= 4) |
| @@ -1875,10 +1862,10 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
| 1875 | #endif /* IDETAPE_DEBUG_LOG */ | 1862 | #endif /* IDETAPE_DEBUG_LOG */ |
| 1876 | 1863 | ||
| 1877 | /* Clear the interrupt */ | 1864 | /* Clear the interrupt */ |
| 1878 | status.all = HWIF(drive)->INB(IDE_STATUS_REG); | 1865 | stat = hwif->INB(IDE_STATUS_REG); |
| 1879 | 1866 | ||
| 1880 | if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { | 1867 | if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { |
| 1881 | if (HWIF(drive)->ide_dma_end(drive) || status.b.check) { | 1868 | if (hwif->ide_dma_end(drive) || (stat & ERR_STAT)) { |
| 1882 | /* | 1869 | /* |
| 1883 | * A DMA error is sometimes expected. For example, | 1870 | * A DMA error is sometimes expected. For example, |
| 1884 | * if the tape is crossing a filemark during a | 1871 | * if the tape is crossing a filemark during a |
| @@ -1912,7 +1899,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
| 1912 | } | 1899 | } |
| 1913 | 1900 | ||
| 1914 | /* No more interrupts */ | 1901 | /* No more interrupts */ |
| 1915 | if (!status.b.drq) { | 1902 | if ((stat & DRQ_STAT) == 0) { |
| 1916 | #if IDETAPE_DEBUG_LOG | 1903 | #if IDETAPE_DEBUG_LOG |
| 1917 | if (tape->debug_level >= 2) | 1904 | if (tape->debug_level >= 2) |
| 1918 | printk(KERN_INFO "ide-tape: Packet command completed, %d bytes transferred\n", pc->actually_transferred); | 1905 | printk(KERN_INFO "ide-tape: Packet command completed, %d bytes transferred\n", pc->actually_transferred); |
| @@ -1927,12 +1914,13 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
| 1927 | (++error_sim_count % 100) == 0) { | 1914 | (++error_sim_count % 100) == 0) { |
| 1928 | printk(KERN_INFO "ide-tape: %s: simulating error\n", | 1915 | printk(KERN_INFO "ide-tape: %s: simulating error\n", |
| 1929 | tape->name); | 1916 | tape->name); |
| 1930 | status.b.check = 1; | 1917 | stat |= ERR_STAT; |
| 1931 | } | 1918 | } |
| 1932 | #endif | 1919 | #endif |
| 1933 | if (status.b.check && pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) | 1920 | if ((stat & ERR_STAT) && pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) |
| 1934 | status.b.check = 0; | 1921 | stat &= ~ERR_STAT; |
| 1935 | if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) { /* Error detected */ | 1922 | if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) { |
| 1923 | /* Error detected */ | ||
| 1936 | #if IDETAPE_DEBUG_LOG | 1924 | #if IDETAPE_DEBUG_LOG |
| 1937 | if (tape->debug_level >= 1) | 1925 | if (tape->debug_level >= 1) |
| 1938 | printk(KERN_INFO "ide-tape: %s: I/O error\n", | 1926 | printk(KERN_INFO "ide-tape: %s: I/O error\n", |
| @@ -1951,7 +1939,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
| 1951 | } | 1939 | } |
| 1952 | pc->error = 0; | 1940 | pc->error = 0; |
| 1953 | if (test_bit(PC_WAIT_FOR_DSC, &pc->flags) && | 1941 | if (test_bit(PC_WAIT_FOR_DSC, &pc->flags) && |
| 1954 | !status.b.dsc) { | 1942 | (stat & SEEK_STAT) == 0) { |
| 1955 | /* Media access command */ | 1943 | /* Media access command */ |
| 1956 | tape->dsc_polling_start = jiffies; | 1944 | tape->dsc_polling_start = jiffies; |
| 1957 | tape->dsc_polling_frequency = IDETAPE_DSC_MA_FAST; | 1945 | tape->dsc_polling_frequency = IDETAPE_DSC_MA_FAST; |
| @@ -1973,30 +1961,30 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
| 1973 | return ide_do_reset(drive); | 1961 | return ide_do_reset(drive); |
| 1974 | } | 1962 | } |
| 1975 | /* Get the number of bytes to transfer on this interrupt. */ | 1963 | /* Get the number of bytes to transfer on this interrupt. */ |
| 1976 | bcount.b.high = hwif->INB(IDE_BCOUNTH_REG); | 1964 | bcount = (hwif->INB(IDE_BCOUNTH_REG) << 8) | |
| 1977 | bcount.b.low = hwif->INB(IDE_BCOUNTL_REG); | 1965 | hwif->INB(IDE_BCOUNTL_REG); |
| 1978 | 1966 | ||
| 1979 | ireason.all = hwif->INB(IDE_IREASON_REG); | 1967 | ireason = hwif->INB(IDE_IREASON_REG); |
| 1980 | 1968 | ||
| 1981 | if (ireason.b.cod) { | 1969 | if (ireason & CD) { |
| 1982 | printk(KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n"); | 1970 | printk(KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n"); |
| 1983 | return ide_do_reset(drive); | 1971 | return ide_do_reset(drive); |
| 1984 | } | 1972 | } |
| 1985 | if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { | 1973 | if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) { |
| 1986 | /* Hopefully, we will never get here */ | 1974 | /* Hopefully, we will never get here */ |
| 1987 | printk(KERN_ERR "ide-tape: We wanted to %s, ", | 1975 | printk(KERN_ERR "ide-tape: We wanted to %s, ", |
| 1988 | ireason.b.io ? "Write":"Read"); | 1976 | (ireason & IO) ? "Write" : "Read"); |
| 1989 | printk(KERN_ERR "ide-tape: but the tape wants us to %s !\n", | 1977 | printk(KERN_ERR "ide-tape: but the tape wants us to %s !\n", |
| 1990 | ireason.b.io ? "Read":"Write"); | 1978 | (ireason & IO) ? "Read" : "Write"); |
| 1991 | return ide_do_reset(drive); | 1979 | return ide_do_reset(drive); |
| 1992 | } | 1980 | } |
| 1993 | if (!test_bit(PC_WRITING, &pc->flags)) { | 1981 | if (!test_bit(PC_WRITING, &pc->flags)) { |
| 1994 | /* Reading - Check that we have enough space */ | 1982 | /* Reading - Check that we have enough space */ |
| 1995 | temp = pc->actually_transferred + bcount.all; | 1983 | temp = pc->actually_transferred + bcount; |
| 1996 | if (temp > pc->request_transfer) { | 1984 | if (temp > pc->request_transfer) { |
| 1997 | if (temp > pc->buffer_size) { | 1985 | if (temp > pc->buffer_size) { |
| 1998 | printk(KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); | 1986 | printk(KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); |
| 1999 | idetape_discard_data(drive, bcount.all); | 1987 | idetape_discard_data(drive, bcount); |
| 2000 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); | 1988 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); |
| 2001 | return ide_started; | 1989 | return ide_started; |
| 2002 | } | 1990 | } |
| @@ -2008,23 +1996,26 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
| 2008 | } | 1996 | } |
| 2009 | if (test_bit(PC_WRITING, &pc->flags)) { | 1997 | if (test_bit(PC_WRITING, &pc->flags)) { |
| 2010 | if (pc->bh != NULL) | 1998 | if (pc->bh != NULL) |
| 2011 | idetape_output_buffers(drive, pc, bcount.all); | 1999 | idetape_output_buffers(drive, pc, bcount); |
| 2012 | else | 2000 | else |
| 2013 | /* Write the current buffer */ | 2001 | /* Write the current buffer */ |
| 2014 | HWIF(drive)->atapi_output_bytes(drive, pc->current_position, bcount.all); | 2002 | hwif->atapi_output_bytes(drive, pc->current_position, |
| 2003 | bcount); | ||
| 2015 | } else { | 2004 | } else { |
| 2016 | if (pc->bh != NULL) | 2005 | if (pc->bh != NULL) |
| 2017 | idetape_input_buffers(drive, pc, bcount.all); | 2006 | idetape_input_buffers(drive, pc, bcount); |
| 2018 | else | 2007 | else |
| 2019 | /* Read the current buffer */ | 2008 | /* Read the current buffer */ |
| 2020 | HWIF(drive)->atapi_input_bytes(drive, pc->current_position, bcount.all); | 2009 | hwif->atapi_input_bytes(drive, pc->current_position, |
| 2010 | bcount); | ||
| 2021 | } | 2011 | } |
| 2022 | /* Update the current position */ | 2012 | /* Update the current position */ |
| 2023 | pc->actually_transferred += bcount.all; | 2013 | pc->actually_transferred += bcount; |
| 2024 | pc->current_position += bcount.all; | 2014 | pc->current_position += bcount; |
| 2025 | #if IDETAPE_DEBUG_LOG | 2015 | #if IDETAPE_DEBUG_LOG |
| 2026 | if (tape->debug_level >= 2) | 2016 | if (tape->debug_level >= 2) |
| 2027 | printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all); | 2017 | printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes " |
| 2018 | "on that interrupt\n", pc->c[0], bcount); | ||
| 2028 | #endif | 2019 | #endif |
| 2029 | /* And set the interrupt handler again */ | 2020 | /* And set the interrupt handler again */ |
| 2030 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); | 2021 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); |
| @@ -2078,28 +2069,28 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) | |||
| 2078 | ide_hwif_t *hwif = drive->hwif; | 2069 | ide_hwif_t *hwif = drive->hwif; |
| 2079 | idetape_tape_t *tape = drive->driver_data; | 2070 | idetape_tape_t *tape = drive->driver_data; |
| 2080 | idetape_pc_t *pc = tape->pc; | 2071 | idetape_pc_t *pc = tape->pc; |
| 2081 | atapi_ireason_t ireason; | ||
| 2082 | int retries = 100; | 2072 | int retries = 100; |
| 2083 | ide_startstop_t startstop; | 2073 | ide_startstop_t startstop; |
| 2074 | u8 ireason; | ||
| 2084 | 2075 | ||
| 2085 | if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { | 2076 | if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { |
| 2086 | printk(KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n"); | 2077 | printk(KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n"); |
| 2087 | return startstop; | 2078 | return startstop; |
| 2088 | } | 2079 | } |
| 2089 | ireason.all = hwif->INB(IDE_IREASON_REG); | 2080 | ireason = hwif->INB(IDE_IREASON_REG); |
| 2090 | while (retries-- && (!ireason.b.cod || ireason.b.io)) { | 2081 | while (retries-- && ((ireason & CD) == 0 || (ireason & IO))) { |
| 2091 | printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing " | 2082 | printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while issuing " |
| 2092 | "a packet command, retrying\n"); | 2083 | "a packet command, retrying\n"); |
| 2093 | udelay(100); | 2084 | udelay(100); |
| 2094 | ireason.all = hwif->INB(IDE_IREASON_REG); | 2085 | ireason = hwif->INB(IDE_IREASON_REG); |
| 2095 | if (retries == 0) { | 2086 | if (retries == 0) { |
| 2096 | printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while " | 2087 | printk(KERN_ERR "ide-tape: (IO,CoD != (0,1) while " |
| 2097 | "issuing a packet command, ignoring\n"); | 2088 | "issuing a packet command, ignoring\n"); |
| 2098 | ireason.b.cod = 1; | 2089 | ireason |= CD; |
| 2099 | ireason.b.io = 0; | 2090 | ireason &= ~IO; |
| 2100 | } | 2091 | } |
| 2101 | } | 2092 | } |
| 2102 | if (!ireason.b.cod || ireason.b.io) { | 2093 | if ((ireason & CD) == 0 || (ireason & IO)) { |
| 2103 | printk(KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing " | 2094 | printk(KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing " |
| 2104 | "a packet command\n"); | 2095 | "a packet command\n"); |
| 2105 | return ide_do_reset(drive); | 2096 | return ide_do_reset(drive); |
| @@ -2120,8 +2111,8 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape | |||
| 2120 | { | 2111 | { |
| 2121 | ide_hwif_t *hwif = drive->hwif; | 2112 | ide_hwif_t *hwif = drive->hwif; |
| 2122 | idetape_tape_t *tape = drive->driver_data; | 2113 | idetape_tape_t *tape = drive->driver_data; |
| 2123 | atapi_bcount_t bcount; | ||
| 2124 | int dma_ok = 0; | 2114 | int dma_ok = 0; |
| 2115 | u16 bcount; | ||
| 2125 | 2116 | ||
| 2126 | #if IDETAPE_DEBUG_BUGS | 2117 | #if IDETAPE_DEBUG_BUGS |
| 2127 | if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD && | 2118 | if (tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD && |
| @@ -2170,7 +2161,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape | |||
| 2170 | pc->actually_transferred = 0; | 2161 | pc->actually_transferred = 0; |
| 2171 | pc->current_position = pc->buffer; | 2162 | pc->current_position = pc->buffer; |
| 2172 | /* Request to transfer the entire buffer at once */ | 2163 | /* Request to transfer the entire buffer at once */ |
| 2173 | bcount.all = pc->request_transfer; | 2164 | bcount = pc->request_transfer; |
| 2174 | 2165 | ||
| 2175 | if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) { | 2166 | if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) { |
| 2176 | printk(KERN_WARNING "ide-tape: DMA disabled, " | 2167 | printk(KERN_WARNING "ide-tape: DMA disabled, " |
| @@ -2180,12 +2171,9 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape | |||
| 2180 | if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) | 2171 | if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) |
| 2181 | dma_ok = !hwif->dma_setup(drive); | 2172 | dma_ok = !hwif->dma_setup(drive); |
| 2182 | 2173 | ||
| 2183 | if (IDE_CONTROL_REG) | 2174 | ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK | |
| 2184 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | 2175 | IDE_TFLAG_OUT_DEVICE, bcount, dma_ok); |
| 2185 | hwif->OUTB(dma_ok ? 1 : 0, IDE_FEATURE_REG); /* Use PIO/DMA */ | 2176 | |
| 2186 | hwif->OUTB(bcount.b.high, IDE_BCOUNTH_REG); | ||
| 2187 | hwif->OUTB(bcount.b.low, IDE_BCOUNTL_REG); | ||
| 2188 | hwif->OUTB(drive->select.all, IDE_SELECT_REG); | ||
| 2189 | if (dma_ok) /* Will begin DMA later */ | 2177 | if (dma_ok) /* Will begin DMA later */ |
| 2190 | set_bit(PC_DMA_IN_PROGRESS, &pc->flags); | 2178 | set_bit(PC_DMA_IN_PROGRESS, &pc->flags); |
| 2191 | if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { | 2179 | if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { |
| @@ -2295,11 +2283,11 @@ static ide_startstop_t idetape_media_access_finished (ide_drive_t *drive) | |||
| 2295 | { | 2283 | { |
| 2296 | idetape_tape_t *tape = drive->driver_data; | 2284 | idetape_tape_t *tape = drive->driver_data; |
| 2297 | idetape_pc_t *pc = tape->pc; | 2285 | idetape_pc_t *pc = tape->pc; |
| 2298 | atapi_status_t status; | 2286 | u8 stat; |
| 2299 | 2287 | ||
| 2300 | status.all = HWIF(drive)->INB(IDE_STATUS_REG); | 2288 | stat = drive->hwif->INB(IDE_STATUS_REG); |
| 2301 | if (status.b.dsc) { | 2289 | if (stat & SEEK_STAT) { |
| 2302 | if (status.b.check) { | 2290 | if (stat & ERR_STAT) { |
| 2303 | /* Error detected */ | 2291 | /* Error detected */ |
| 2304 | if (pc->c[0] != IDETAPE_TEST_UNIT_READY_CMD) | 2292 | if (pc->c[0] != IDETAPE_TEST_UNIT_READY_CMD) |
| 2305 | printk(KERN_ERR "ide-tape: %s: I/O error, ", | 2293 | printk(KERN_ERR "ide-tape: %s: I/O error, ", |
| @@ -2417,7 +2405,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
| 2417 | idetape_tape_t *tape = drive->driver_data; | 2405 | idetape_tape_t *tape = drive->driver_data; |
| 2418 | idetape_pc_t *pc = NULL; | 2406 | idetape_pc_t *pc = NULL; |
| 2419 | struct request *postponed_rq = tape->postponed_rq; | 2407 | struct request *postponed_rq = tape->postponed_rq; |
| 2420 | atapi_status_t status; | 2408 | u8 stat; |
| 2421 | 2409 | ||
| 2422 | #if IDETAPE_DEBUG_LOG | 2410 | #if IDETAPE_DEBUG_LOG |
| 2423 | #if 0 | 2411 | #if 0 |
| @@ -2465,7 +2453,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
| 2465 | * If the tape is still busy, postpone our request and service | 2453 | * If the tape is still busy, postpone our request and service |
| 2466 | * the other device meanwhile. | 2454 | * the other device meanwhile. |
| 2467 | */ | 2455 | */ |
| 2468 | status.all = HWIF(drive)->INB(IDE_STATUS_REG); | 2456 | stat = drive->hwif->INB(IDE_STATUS_REG); |
| 2469 | 2457 | ||
| 2470 | if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2)) | 2458 | if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2)) |
| 2471 | set_bit(IDETAPE_IGNORE_DSC, &tape->flags); | 2459 | set_bit(IDETAPE_IGNORE_DSC, &tape->flags); |
| @@ -2481,7 +2469,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
| 2481 | tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time); | 2469 | tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time); |
| 2482 | calculate_speeds(drive); | 2470 | calculate_speeds(drive); |
| 2483 | if (!test_and_clear_bit(IDETAPE_IGNORE_DSC, &tape->flags) && | 2471 | if (!test_and_clear_bit(IDETAPE_IGNORE_DSC, &tape->flags) && |
| 2484 | !status.b.dsc) { | 2472 | (stat & SEEK_STAT) == 0) { |
| 2485 | if (postponed_rq == NULL) { | 2473 | if (postponed_rq == NULL) { |
| 2486 | tape->dsc_polling_start = jiffies; | 2474 | tape->dsc_polling_start = jiffies; |
| 2487 | tape->dsc_polling_frequency = tape->best_dsc_rw_frequency; | 2475 | tape->dsc_polling_frequency = tape->best_dsc_rw_frequency; |
| @@ -2502,9 +2490,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
| 2502 | } | 2490 | } |
| 2503 | if (rq->cmd[0] & REQ_IDETAPE_READ) { | 2491 | if (rq->cmd[0] & REQ_IDETAPE_READ) { |
| 2504 | tape->buffer_head++; | 2492 | tape->buffer_head++; |
| 2505 | #if USE_IOTRACE | ||
| 2506 | IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor); | ||
| 2507 | #endif | ||
| 2508 | tape->postpone_cnt = 0; | 2493 | tape->postpone_cnt = 0; |
| 2509 | pc = idetape_next_pc_storage(drive); | 2494 | pc = idetape_next_pc_storage(drive); |
| 2510 | idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); | 2495 | idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); |
| @@ -2512,9 +2497,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
| 2512 | } | 2497 | } |
| 2513 | if (rq->cmd[0] & REQ_IDETAPE_WRITE) { | 2498 | if (rq->cmd[0] & REQ_IDETAPE_WRITE) { |
| 2514 | tape->buffer_head++; | 2499 | tape->buffer_head++; |
| 2515 | #if USE_IOTRACE | ||
| 2516 | IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor); | ||
| 2517 | #endif | ||
| 2518 | tape->postpone_cnt = 0; | 2500 | tape->postpone_cnt = 0; |
| 2519 | pc = idetape_next_pc_storage(drive); | 2501 | pc = idetape_next_pc_storage(drive); |
| 2520 | idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); | 2502 | idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); |
| @@ -3241,9 +3223,6 @@ static int idetape_add_chrdev_write_request (ide_drive_t *drive, int blocks) | |||
| 3241 | idetape_switch_buffers(tape, new_stage); | 3223 | idetape_switch_buffers(tape, new_stage); |
| 3242 | idetape_add_stage_tail(drive, new_stage); | 3224 | idetape_add_stage_tail(drive, new_stage); |
| 3243 | tape->pipeline_head++; | 3225 | tape->pipeline_head++; |
| 3244 | #if USE_IOTRACE | ||
| 3245 | IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor); | ||
| 3246 | #endif | ||
| 3247 | calculate_speeds(drive); | 3226 | calculate_speeds(drive); |
| 3248 | 3227 | ||
| 3249 | /* | 3228 | /* |
| @@ -3493,9 +3472,6 @@ static int idetape_add_chrdev_read_request (ide_drive_t *drive,int blocks) | |||
| 3493 | idetape_remove_stage_head(drive); | 3472 | idetape_remove_stage_head(drive); |
| 3494 | spin_unlock_irqrestore(&tape->spinlock, flags); | 3473 | spin_unlock_irqrestore(&tape->spinlock, flags); |
| 3495 | tape->pipeline_head++; | 3474 | tape->pipeline_head++; |
| 3496 | #if USE_IOTRACE | ||
| 3497 | IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor); | ||
| 3498 | #endif | ||
| 3499 | calculate_speeds(drive); | 3475 | calculate_speeds(drive); |
| 3500 | } | 3476 | } |
| 3501 | #if IDETAPE_DEBUG_BUGS | 3477 | #if IDETAPE_DEBUG_BUGS |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 2b60f1b0437e..2d63ea9ee61b 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
| @@ -63,65 +63,78 @@ static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount) | |||
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | ||
| 67 | { | ||
| 68 | ide_hwif_t *hwif = drive->hwif; | ||
| 69 | struct ide_taskfile *tf = &task->tf; | ||
| 70 | u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | ||
| 71 | |||
| 72 | if (task->tf_flags & IDE_TFLAG_FLAGGED) | ||
| 73 | HIHI = 0xFF; | ||
| 74 | |||
| 75 | #ifdef DEBUG | ||
| 76 | printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x " | ||
| 77 | "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n", | ||
| 78 | drive->name, tf->feature, tf->nsect, tf->lbal, | ||
| 79 | tf->lbam, tf->lbah, tf->device, tf->command); | ||
| 80 | #endif | ||
| 81 | |||
| 82 | if (IDE_CONTROL_REG) | ||
| 83 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ | ||
| 84 | |||
| 85 | if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0) | ||
| 86 | SELECT_MASK(drive, 0); | ||
| 87 | |||
| 88 | if (task->tf_flags & IDE_TFLAG_OUT_DATA) | ||
| 89 | hwif->OUTW((tf->hob_data << 8) | tf->data, IDE_DATA_REG); | ||
| 90 | |||
| 91 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
| 92 | hwif->OUTB(tf->hob_feature, IDE_FEATURE_REG); | ||
| 93 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
| 94 | hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG); | ||
| 95 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
| 96 | hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG); | ||
| 97 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
| 98 | hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG); | ||
| 99 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
| 100 | hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG); | ||
| 101 | |||
| 102 | if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
| 103 | hwif->OUTB(tf->feature, IDE_FEATURE_REG); | ||
| 104 | if (task->tf_flags & IDE_TFLAG_OUT_NSECT) | ||
| 105 | hwif->OUTB(tf->nsect, IDE_NSECTOR_REG); | ||
| 106 | if (task->tf_flags & IDE_TFLAG_OUT_LBAL) | ||
| 107 | hwif->OUTB(tf->lbal, IDE_SECTOR_REG); | ||
| 108 | if (task->tf_flags & IDE_TFLAG_OUT_LBAM) | ||
| 109 | hwif->OUTB(tf->lbam, IDE_LCYL_REG); | ||
| 110 | if (task->tf_flags & IDE_TFLAG_OUT_LBAH) | ||
| 111 | hwif->OUTB(tf->lbah, IDE_HCYL_REG); | ||
| 112 | |||
| 113 | if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) | ||
| 114 | hwif->OUTB((tf->device & HIHI) | drive->select.all, IDE_SELECT_REG); | ||
| 115 | } | ||
| 116 | |||
| 66 | int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | 117 | int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) |
| 67 | { | 118 | { |
| 68 | ide_task_t args; | 119 | ide_task_t args; |
| 120 | |||
| 69 | memset(&args, 0, sizeof(ide_task_t)); | 121 | memset(&args, 0, sizeof(ide_task_t)); |
| 70 | args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01; | 122 | args.tf.nsect = 0x01; |
| 71 | if (drive->media == ide_disk) | 123 | if (drive->media == ide_disk) |
| 72 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_IDENTIFY; | 124 | args.tf.command = WIN_IDENTIFY; |
| 73 | else | 125 | else |
| 74 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_PIDENTIFY; | 126 | args.tf.command = WIN_PIDENTIFY; |
| 75 | args.command_type = IDE_DRIVE_TASK_IN; | 127 | args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 76 | args.data_phase = TASKFILE_IN; | 128 | args.data_phase = TASKFILE_IN; |
| 77 | args.handler = &task_in_intr; | 129 | return ide_raw_taskfile(drive, &args, buf, 1); |
| 78 | return ide_raw_taskfile(drive, &args, buf); | ||
| 79 | } | 130 | } |
| 80 | 131 | ||
| 81 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | 132 | static int inline task_dma_ok(ide_task_t *task) |
| 82 | { | 133 | { |
| 83 | ide_hwif_t *hwif = HWIF(drive); | 134 | if (blk_fs_request(task->rq) || (task->tf_flags & IDE_TFLAG_FLAGGED)) |
| 84 | task_struct_t *taskfile = (task_struct_t *) task->tfRegister; | 135 | return 1; |
| 85 | hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; | ||
| 86 | u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF; | ||
| 87 | |||
| 88 | /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ | ||
| 89 | if (IDE_CONTROL_REG) { | ||
| 90 | /* clear nIEN */ | ||
| 91 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | ||
| 92 | } | ||
| 93 | SELECT_MASK(drive, 0); | ||
| 94 | |||
| 95 | if (drive->addressing == 1) { | ||
| 96 | hwif->OUTB(hobfile->feature, IDE_FEATURE_REG); | ||
| 97 | hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); | ||
| 98 | hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); | ||
| 99 | hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); | ||
| 100 | hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); | ||
| 101 | } | ||
| 102 | |||
| 103 | hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); | ||
| 104 | hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); | ||
| 105 | hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); | ||
| 106 | hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); | ||
| 107 | hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); | ||
| 108 | |||
| 109 | hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); | ||
| 110 | |||
| 111 | if (task->handler != NULL) { | ||
| 112 | if (task->prehandler != NULL) { | ||
| 113 | hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); | ||
| 114 | ndelay(400); /* FIXME */ | ||
| 115 | return task->prehandler(drive, task->rq); | ||
| 116 | } | ||
| 117 | ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); | ||
| 118 | return ide_started; | ||
| 119 | } | ||
| 120 | |||
| 121 | if (!drive->using_dma) | ||
| 122 | return ide_stopped; | ||
| 123 | 136 | ||
| 124 | switch (taskfile->command) { | 137 | switch (task->tf.command) { |
| 125 | case WIN_WRITEDMA_ONCE: | 138 | case WIN_WRITEDMA_ONCE: |
| 126 | case WIN_WRITEDMA: | 139 | case WIN_WRITEDMA: |
| 127 | case WIN_WRITEDMA_EXT: | 140 | case WIN_WRITEDMA_EXT: |
| @@ -129,24 +142,79 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
| 129 | case WIN_READDMA: | 142 | case WIN_READDMA: |
| 130 | case WIN_READDMA_EXT: | 143 | case WIN_READDMA_EXT: |
| 131 | case WIN_IDENTIFY_DMA: | 144 | case WIN_IDENTIFY_DMA: |
| 132 | if (!hwif->dma_setup(drive)) { | 145 | return 1; |
| 133 | hwif->dma_exec_cmd(drive, taskfile->command); | ||
| 134 | hwif->dma_start(drive); | ||
| 135 | return ide_started; | ||
| 136 | } | ||
| 137 | break; | ||
| 138 | default: | ||
| 139 | if (task->handler == NULL) | ||
| 140 | return ide_stopped; | ||
| 141 | } | 146 | } |
| 142 | 147 | ||
| 143 | return ide_stopped; | 148 | return 0; |
| 149 | } | ||
| 150 | |||
| 151 | static ide_startstop_t task_no_data_intr(ide_drive_t *); | ||
| 152 | static ide_startstop_t set_geometry_intr(ide_drive_t *); | ||
| 153 | static ide_startstop_t recal_intr(ide_drive_t *); | ||
| 154 | static ide_startstop_t set_multmode_intr(ide_drive_t *); | ||
| 155 | static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); | ||
| 156 | static ide_startstop_t task_in_intr(ide_drive_t *); | ||
| 157 | |||
| 158 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | ||
| 159 | { | ||
| 160 | ide_hwif_t *hwif = HWIF(drive); | ||
| 161 | struct ide_taskfile *tf = &task->tf; | ||
| 162 | ide_handler_t *handler = NULL; | ||
| 163 | |||
| 164 | if (task->data_phase == TASKFILE_MULTI_IN || | ||
| 165 | task->data_phase == TASKFILE_MULTI_OUT) { | ||
| 166 | if (!drive->mult_count) { | ||
| 167 | printk(KERN_ERR "%s: multimode not set!\n", | ||
| 168 | drive->name); | ||
| 169 | return ide_stopped; | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | if (task->tf_flags & IDE_TFLAG_FLAGGED) | ||
| 174 | task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS; | ||
| 175 | |||
| 176 | if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) | ||
| 177 | ide_tf_load(drive, task); | ||
| 178 | |||
| 179 | switch (task->data_phase) { | ||
| 180 | case TASKFILE_MULTI_OUT: | ||
| 181 | case TASKFILE_OUT: | ||
| 182 | hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG); | ||
| 183 | ndelay(400); /* FIXME */ | ||
| 184 | return pre_task_out_intr(drive, task->rq); | ||
| 185 | case TASKFILE_MULTI_IN: | ||
| 186 | case TASKFILE_IN: | ||
| 187 | handler = task_in_intr; | ||
| 188 | /* fall-through */ | ||
| 189 | case TASKFILE_NO_DATA: | ||
| 190 | if (handler == NULL) | ||
| 191 | handler = task_no_data_intr; | ||
| 192 | /* WIN_{SPECIFY,RESTORE,SETMULT} use custom handlers */ | ||
| 193 | if (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) { | ||
| 194 | switch (tf->command) { | ||
| 195 | case WIN_SPECIFY: handler = set_geometry_intr; break; | ||
| 196 | case WIN_RESTORE: handler = recal_intr; break; | ||
| 197 | case WIN_SETMULT: handler = set_multmode_intr; break; | ||
| 198 | } | ||
| 199 | } | ||
| 200 | ide_execute_command(drive, tf->command, handler, | ||
| 201 | WAIT_WORSTCASE, NULL); | ||
| 202 | return ide_started; | ||
| 203 | default: | ||
| 204 | if (task_dma_ok(task) == 0 || drive->using_dma == 0 || | ||
| 205 | hwif->dma_setup(drive)) | ||
| 206 | return ide_stopped; | ||
| 207 | hwif->dma_exec_cmd(drive, tf->command); | ||
| 208 | hwif->dma_start(drive); | ||
| 209 | return ide_started; | ||
| 210 | } | ||
| 144 | } | 211 | } |
| 212 | EXPORT_SYMBOL_GPL(do_rw_taskfile); | ||
| 145 | 213 | ||
| 146 | /* | 214 | /* |
| 147 | * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. | 215 | * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. |
| 148 | */ | 216 | */ |
| 149 | ide_startstop_t set_multmode_intr (ide_drive_t *drive) | 217 | static ide_startstop_t set_multmode_intr(ide_drive_t *drive) |
| 150 | { | 218 | { |
| 151 | ide_hwif_t *hwif = HWIF(drive); | 219 | ide_hwif_t *hwif = HWIF(drive); |
| 152 | u8 stat; | 220 | u8 stat; |
| @@ -164,7 +232,7 @@ ide_startstop_t set_multmode_intr (ide_drive_t *drive) | |||
| 164 | /* | 232 | /* |
| 165 | * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd. | 233 | * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd. |
| 166 | */ | 234 | */ |
| 167 | ide_startstop_t set_geometry_intr (ide_drive_t *drive) | 235 | static ide_startstop_t set_geometry_intr(ide_drive_t *drive) |
| 168 | { | 236 | { |
| 169 | ide_hwif_t *hwif = HWIF(drive); | 237 | ide_hwif_t *hwif = HWIF(drive); |
| 170 | int retries = 5; | 238 | int retries = 5; |
| @@ -187,7 +255,7 @@ ide_startstop_t set_geometry_intr (ide_drive_t *drive) | |||
| 187 | /* | 255 | /* |
| 188 | * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd. | 256 | * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd. |
| 189 | */ | 257 | */ |
| 190 | ide_startstop_t recal_intr (ide_drive_t *drive) | 258 | static ide_startstop_t recal_intr(ide_drive_t *drive) |
| 191 | { | 259 | { |
| 192 | ide_hwif_t *hwif = HWIF(drive); | 260 | ide_hwif_t *hwif = HWIF(drive); |
| 193 | u8 stat; | 261 | u8 stat; |
| @@ -200,7 +268,7 @@ ide_startstop_t recal_intr (ide_drive_t *drive) | |||
| 200 | /* | 268 | /* |
| 201 | * Handler for commands without a data phase | 269 | * Handler for commands without a data phase |
| 202 | */ | 270 | */ |
| 203 | ide_startstop_t task_no_data_intr (ide_drive_t *drive) | 271 | static ide_startstop_t task_no_data_intr(ide_drive_t *drive) |
| 204 | { | 272 | { |
| 205 | ide_task_t *args = HWGROUP(drive)->rq->special; | 273 | ide_task_t *args = HWGROUP(drive)->rq->special; |
| 206 | ide_hwif_t *hwif = HWIF(drive); | 274 | ide_hwif_t *hwif = HWIF(drive); |
| @@ -217,8 +285,6 @@ ide_startstop_t task_no_data_intr (ide_drive_t *drive) | |||
| 217 | return ide_stopped; | 285 | return ide_stopped; |
| 218 | } | 286 | } |
| 219 | 287 | ||
| 220 | EXPORT_SYMBOL(task_no_data_intr); | ||
| 221 | |||
| 222 | static u8 wait_drive_not_busy(ide_drive_t *drive) | 288 | static u8 wait_drive_not_busy(ide_drive_t *drive) |
| 223 | { | 289 | { |
| 224 | ide_hwif_t *hwif = HWIF(drive); | 290 | ide_hwif_t *hwif = HWIF(drive); |
| @@ -363,7 +429,7 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | |||
| 363 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | 429 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
| 364 | ide_task_t *task = rq->special; | 430 | ide_task_t *task = rq->special; |
| 365 | 431 | ||
| 366 | if (task->tf_out_flags.all) { | 432 | if (task->tf_flags & IDE_TFLAG_FLAGGED) { |
| 367 | u8 err = drive->hwif->INB(IDE_ERROR_REG); | 433 | u8 err = drive->hwif->INB(IDE_ERROR_REG); |
| 368 | ide_end_drive_cmd(drive, stat, err); | 434 | ide_end_drive_cmd(drive, stat, err); |
| 369 | return; | 435 | return; |
| @@ -382,7 +448,7 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | |||
| 382 | /* | 448 | /* |
| 383 | * Handler for command with PIO data-in phase (Read/Read Multiple). | 449 | * Handler for command with PIO data-in phase (Read/Read Multiple). |
| 384 | */ | 450 | */ |
| 385 | ide_startstop_t task_in_intr (ide_drive_t *drive) | 451 | static ide_startstop_t task_in_intr(ide_drive_t *drive) |
| 386 | { | 452 | { |
| 387 | ide_hwif_t *hwif = drive->hwif; | 453 | ide_hwif_t *hwif = drive->hwif; |
| 388 | struct request *rq = HWGROUP(drive)->rq; | 454 | struct request *rq = HWGROUP(drive)->rq; |
| @@ -413,7 +479,6 @@ ide_startstop_t task_in_intr (ide_drive_t *drive) | |||
| 413 | 479 | ||
| 414 | return ide_started; | 480 | return ide_started; |
| 415 | } | 481 | } |
| 416 | EXPORT_SYMBOL(task_in_intr); | ||
| 417 | 482 | ||
| 418 | /* | 483 | /* |
| 419 | * Handler for command with PIO data-out phase (Write/Write Multiple). | 484 | * Handler for command with PIO data-out phase (Write/Write Multiple). |
| @@ -443,7 +508,7 @@ static ide_startstop_t task_out_intr (ide_drive_t *drive) | |||
| 443 | return ide_started; | 508 | return ide_started; |
| 444 | } | 509 | } |
| 445 | 510 | ||
| 446 | ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) | 511 | static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) |
| 447 | { | 512 | { |
| 448 | ide_startstop_t startstop; | 513 | ide_startstop_t startstop; |
| 449 | 514 | ||
| @@ -464,9 +529,8 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) | |||
| 464 | 529 | ||
| 465 | return ide_started; | 530 | return ide_started; |
| 466 | } | 531 | } |
| 467 | EXPORT_SYMBOL(pre_task_out_intr); | ||
| 468 | 532 | ||
| 469 | static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf) | 533 | int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect) |
| 470 | { | 534 | { |
| 471 | struct request rq; | 535 | struct request rq; |
| 472 | 536 | ||
| @@ -481,36 +545,27 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long | |||
| 481 | * if we would find a solution to transfer any size. | 545 | * if we would find a solution to transfer any size. |
| 482 | * To support special commands like READ LONG. | 546 | * To support special commands like READ LONG. |
| 483 | */ | 547 | */ |
| 484 | if (args->command_type != IDE_DRIVE_TASK_NO_DATA) { | 548 | rq.hard_nr_sectors = rq.nr_sectors = nsect; |
| 485 | if (data_size == 0) | 549 | rq.hard_cur_sectors = rq.current_nr_sectors = nsect; |
| 486 | rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET]; | ||
| 487 | else | ||
| 488 | rq.nr_sectors = data_size / SECTOR_SIZE; | ||
| 489 | |||
| 490 | if (!rq.nr_sectors) { | ||
| 491 | printk(KERN_ERR "%s: in/out command without data\n", | ||
| 492 | drive->name); | ||
| 493 | return -EFAULT; | ||
| 494 | } | ||
| 495 | 550 | ||
| 496 | rq.hard_nr_sectors = rq.nr_sectors; | 551 | if (task->tf_flags & IDE_TFLAG_WRITE) |
| 497 | rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors; | 552 | rq.cmd_flags |= REQ_RW; |
| 498 | 553 | ||
| 499 | if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) | 554 | rq.special = task; |
| 500 | rq.cmd_flags |= REQ_RW; | 555 | task->rq = &rq; |
| 501 | } | ||
| 502 | 556 | ||
| 503 | rq.special = args; | ||
| 504 | args->rq = &rq; | ||
| 505 | return ide_do_drive_cmd(drive, &rq, ide_wait); | 557 | return ide_do_drive_cmd(drive, &rq, ide_wait); |
| 506 | } | 558 | } |
| 507 | 559 | ||
| 508 | int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf) | 560 | EXPORT_SYMBOL(ide_raw_taskfile); |
| 561 | |||
| 562 | int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task) | ||
| 509 | { | 563 | { |
| 510 | return ide_diag_taskfile(drive, args, 0, buf); | 564 | task->data_phase = TASKFILE_NO_DATA; |
| 511 | } | ||
| 512 | 565 | ||
| 513 | EXPORT_SYMBOL(ide_raw_taskfile); | 566 | return ide_raw_taskfile(drive, task, NULL, 0); |
| 567 | } | ||
| 568 | EXPORT_SYMBOL_GPL(ide_no_data_taskfile); | ||
| 514 | 569 | ||
| 515 | #ifdef CONFIG_IDE_TASK_IOCTL | 570 | #ifdef CONFIG_IDE_TASK_IOCTL |
| 516 | int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | 571 | int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) |
| @@ -519,12 +574,12 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
| 519 | ide_task_t args; | 574 | ide_task_t args; |
| 520 | u8 *outbuf = NULL; | 575 | u8 *outbuf = NULL; |
| 521 | u8 *inbuf = NULL; | 576 | u8 *inbuf = NULL; |
| 522 | task_ioreg_t *argsptr = args.tfRegister; | 577 | u8 *data_buf = NULL; |
| 523 | task_ioreg_t *hobsptr = args.hobRegister; | ||
| 524 | int err = 0; | 578 | int err = 0; |
| 525 | int tasksize = sizeof(struct ide_task_request_s); | 579 | int tasksize = sizeof(struct ide_task_request_s); |
| 526 | unsigned int taskin = 0; | 580 | unsigned int taskin = 0; |
| 527 | unsigned int taskout = 0; | 581 | unsigned int taskout = 0; |
| 582 | u16 nsect = 0; | ||
| 528 | u8 io_32bit = drive->io_32bit; | 583 | u8 io_32bit = drive->io_32bit; |
| 529 | char __user *buf = (char __user *)arg; | 584 | char __user *buf = (char __user *)arg; |
| 530 | 585 | ||
| @@ -572,24 +627,52 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
| 572 | } | 627 | } |
| 573 | 628 | ||
| 574 | memset(&args, 0, sizeof(ide_task_t)); | 629 | memset(&args, 0, sizeof(ide_task_t)); |
| 575 | memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); | ||
| 576 | memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE); | ||
| 577 | 630 | ||
| 578 | args.tf_in_flags = req_task->in_flags; | 631 | memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2); |
| 579 | args.tf_out_flags = req_task->out_flags; | 632 | memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); |
| 580 | args.data_phase = req_task->data_phase; | 633 | |
| 581 | args.command_type = req_task->req_cmd; | 634 | args.data_phase = req_task->data_phase; |
| 635 | |||
| 636 | args.tf_flags = IDE_TFLAG_OUT_DEVICE; | ||
| 637 | if (drive->addressing == 1) | ||
| 638 | args.tf_flags |= IDE_TFLAG_LBA48; | ||
| 639 | |||
| 640 | if (req_task->out_flags.all) { | ||
| 641 | args.tf_flags |= IDE_TFLAG_FLAGGED; | ||
| 642 | |||
| 643 | if (req_task->out_flags.b.data) | ||
| 644 | args.tf_flags |= IDE_TFLAG_OUT_DATA; | ||
| 645 | |||
| 646 | if (req_task->out_flags.b.nsector_hob) | ||
| 647 | args.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT; | ||
| 648 | if (req_task->out_flags.b.sector_hob) | ||
| 649 | args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL; | ||
| 650 | if (req_task->out_flags.b.lcyl_hob) | ||
| 651 | args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM; | ||
| 652 | if (req_task->out_flags.b.hcyl_hob) | ||
| 653 | args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH; | ||
| 654 | |||
| 655 | if (req_task->out_flags.b.error_feature) | ||
| 656 | args.tf_flags |= IDE_TFLAG_OUT_FEATURE; | ||
| 657 | if (req_task->out_flags.b.nsector) | ||
| 658 | args.tf_flags |= IDE_TFLAG_OUT_NSECT; | ||
| 659 | if (req_task->out_flags.b.sector) | ||
| 660 | args.tf_flags |= IDE_TFLAG_OUT_LBAL; | ||
| 661 | if (req_task->out_flags.b.lcyl) | ||
| 662 | args.tf_flags |= IDE_TFLAG_OUT_LBAM; | ||
| 663 | if (req_task->out_flags.b.hcyl) | ||
| 664 | args.tf_flags |= IDE_TFLAG_OUT_LBAH; | ||
| 665 | } else { | ||
| 666 | args.tf_flags |= IDE_TFLAG_OUT_TF; | ||
| 667 | if (args.tf_flags & IDE_TFLAG_LBA48) | ||
| 668 | args.tf_flags |= IDE_TFLAG_OUT_HOB; | ||
| 669 | } | ||
| 670 | |||
| 671 | if (req_task->in_flags.b.data) | ||
| 672 | args.tf_flags |= IDE_TFLAG_IN_DATA; | ||
| 582 | 673 | ||
| 583 | drive->io_32bit = 0; | 674 | drive->io_32bit = 0; |
| 584 | switch(req_task->data_phase) { | 675 | switch(req_task->data_phase) { |
| 585 | case TASKFILE_OUT_DMAQ: | ||
| 586 | case TASKFILE_OUT_DMA: | ||
| 587 | err = ide_diag_taskfile(drive, &args, taskout, outbuf); | ||
| 588 | break; | ||
| 589 | case TASKFILE_IN_DMAQ: | ||
| 590 | case TASKFILE_IN_DMA: | ||
| 591 | err = ide_diag_taskfile(drive, &args, taskin, inbuf); | ||
| 592 | break; | ||
| 593 | case TASKFILE_MULTI_OUT: | 676 | case TASKFILE_MULTI_OUT: |
| 594 | if (!drive->mult_count) { | 677 | if (!drive->mult_count) { |
| 595 | /* (hs): give up if multcount is not set */ | 678 | /* (hs): give up if multcount is not set */ |
| @@ -601,9 +684,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
| 601 | } | 684 | } |
| 602 | /* fall through */ | 685 | /* fall through */ |
| 603 | case TASKFILE_OUT: | 686 | case TASKFILE_OUT: |
| 604 | args.prehandler = &pre_task_out_intr; | 687 | /* fall through */ |
| 605 | args.handler = &task_out_intr; | 688 | case TASKFILE_OUT_DMAQ: |
| 606 | err = ide_diag_taskfile(drive, &args, taskout, outbuf); | 689 | case TASKFILE_OUT_DMA: |
| 690 | nsect = taskout / SECTOR_SIZE; | ||
| 691 | data_buf = outbuf; | ||
| 607 | break; | 692 | break; |
| 608 | case TASKFILE_MULTI_IN: | 693 | case TASKFILE_MULTI_IN: |
| 609 | if (!drive->mult_count) { | 694 | if (!drive->mult_count) { |
| @@ -616,22 +701,46 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
| 616 | } | 701 | } |
| 617 | /* fall through */ | 702 | /* fall through */ |
| 618 | case TASKFILE_IN: | 703 | case TASKFILE_IN: |
| 619 | args.handler = &task_in_intr; | 704 | /* fall through */ |
| 620 | err = ide_diag_taskfile(drive, &args, taskin, inbuf); | 705 | case TASKFILE_IN_DMAQ: |
| 706 | case TASKFILE_IN_DMA: | ||
| 707 | nsect = taskin / SECTOR_SIZE; | ||
| 708 | data_buf = inbuf; | ||
| 621 | break; | 709 | break; |
| 622 | case TASKFILE_NO_DATA: | 710 | case TASKFILE_NO_DATA: |
| 623 | args.handler = &task_no_data_intr; | ||
| 624 | err = ide_diag_taskfile(drive, &args, 0, NULL); | ||
| 625 | break; | 711 | break; |
| 626 | default: | 712 | default: |
| 627 | err = -EFAULT; | 713 | err = -EFAULT; |
| 628 | goto abort; | 714 | goto abort; |
| 629 | } | 715 | } |
| 630 | 716 | ||
| 631 | memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE); | 717 | if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA) |
| 632 | memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE); | 718 | nsect = 0; |
| 633 | req_task->in_flags = args.tf_in_flags; | 719 | else if (!nsect) { |
| 634 | req_task->out_flags = args.tf_out_flags; | 720 | nsect = (args.tf.hob_nsect << 8) | args.tf.nsect; |
| 721 | |||
| 722 | if (!nsect) { | ||
| 723 | printk(KERN_ERR "%s: in/out command without data\n", | ||
| 724 | drive->name); | ||
| 725 | err = -EFAULT; | ||
| 726 | goto abort; | ||
| 727 | } | ||
| 728 | } | ||
| 729 | |||
| 730 | if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) | ||
| 731 | args.tf_flags |= IDE_TFLAG_WRITE; | ||
| 732 | |||
| 733 | err = ide_raw_taskfile(drive, &args, data_buf, nsect); | ||
| 734 | |||
| 735 | memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2); | ||
| 736 | memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE); | ||
| 737 | |||
| 738 | if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) && | ||
| 739 | req_task->in_flags.all == 0) { | ||
| 740 | req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; | ||
| 741 | if (drive->addressing == 1) | ||
| 742 | req_task->in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8); | ||
| 743 | } | ||
| 635 | 744 | ||
| 636 | if (copy_to_user(buf, req_task, tasksize)) { | 745 | if (copy_to_user(buf, req_task, tasksize)) { |
| 637 | err = -EFAULT; | 746 | err = -EFAULT; |
| @@ -688,6 +797,7 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
| 688 | u8 xfer_rate = 0; | 797 | u8 xfer_rate = 0; |
| 689 | int argsize = 4; | 798 | int argsize = 4; |
| 690 | ide_task_t tfargs; | 799 | ide_task_t tfargs; |
| 800 | struct ide_taskfile *tf = &tfargs.tf; | ||
| 691 | 801 | ||
| 692 | if (NULL == (void *) arg) { | 802 | if (NULL == (void *) arg) { |
| 693 | struct request rq; | 803 | struct request rq; |
| @@ -699,13 +809,10 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
| 699 | return -EFAULT; | 809 | return -EFAULT; |
| 700 | 810 | ||
| 701 | memset(&tfargs, 0, sizeof(ide_task_t)); | 811 | memset(&tfargs, 0, sizeof(ide_task_t)); |
| 702 | tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2]; | 812 | tf->feature = args[2]; |
| 703 | tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3]; | 813 | tf->nsect = args[3]; |
| 704 | tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1]; | 814 | tf->lbal = args[1]; |
| 705 | tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00; | 815 | tf->command = args[0]; |
| 706 | tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00; | ||
| 707 | tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00; | ||
| 708 | tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0]; | ||
| 709 | 816 | ||
| 710 | if (args[3]) { | 817 | if (args[3]) { |
| 711 | argsize = 4 + (SECTOR_WORDS * 4 * args[3]); | 818 | argsize = 4 + (SECTOR_WORDS * 4 * args[3]); |
| @@ -734,135 +841,28 @@ abort: | |||
| 734 | return err; | 841 | return err; |
| 735 | } | 842 | } |
| 736 | 843 | ||
| 737 | static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf) | ||
| 738 | { | ||
| 739 | struct request rq; | ||
| 740 | |||
| 741 | ide_init_drive_cmd(&rq); | ||
| 742 | rq.cmd_type = REQ_TYPE_ATA_TASK; | ||
| 743 | rq.buffer = buf; | ||
| 744 | return ide_do_drive_cmd(drive, &rq, ide_wait); | ||
| 745 | } | ||
| 746 | |||
| 747 | int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | 844 | int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) |
| 748 | { | 845 | { |
| 749 | void __user *p = (void __user *)arg; | 846 | void __user *p = (void __user *)arg; |
| 750 | int err = 0; | 847 | int err = 0; |
| 751 | u8 args[7], *argbuf = args; | 848 | u8 args[7]; |
| 752 | int argsize = 7; | 849 | ide_task_t task; |
| 753 | 850 | ||
| 754 | if (copy_from_user(args, p, 7)) | 851 | if (copy_from_user(args, p, 7)) |
| 755 | return -EFAULT; | 852 | return -EFAULT; |
| 756 | err = ide_wait_cmd_task(drive, argbuf); | ||
| 757 | if (copy_to_user(p, argbuf, argsize)) | ||
| 758 | err = -EFAULT; | ||
| 759 | return err; | ||
| 760 | } | ||
| 761 | |||
| 762 | /* | ||
| 763 | * NOTICE: This is additions from IBM to provide a discrete interface, | ||
| 764 | * for selective taskregister access operations. Nice JOB Klaus!!! | ||
| 765 | * Glad to be able to work and co-develop this with you and IBM. | ||
| 766 | */ | ||
| 767 | ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) | ||
| 768 | { | ||
| 769 | ide_hwif_t *hwif = HWIF(drive); | ||
| 770 | task_struct_t *taskfile = (task_struct_t *) task->tfRegister; | ||
| 771 | hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; | ||
| 772 | |||
| 773 | if (task->data_phase == TASKFILE_MULTI_IN || | ||
| 774 | task->data_phase == TASKFILE_MULTI_OUT) { | ||
| 775 | if (!drive->mult_count) { | ||
| 776 | printk(KERN_ERR "%s: multimode not set!\n", drive->name); | ||
| 777 | return ide_stopped; | ||
| 778 | } | ||
| 779 | } | ||
| 780 | |||
| 781 | /* | ||
| 782 | * (ks) Check taskfile in flags. | ||
| 783 | * If set, then execute as it is defined. | ||
| 784 | * If not set, then define default settings. | ||
| 785 | * The default values are: | ||
| 786 | * read all taskfile registers (except data) | ||
| 787 | * read the hob registers (sector, nsector, lcyl, hcyl) | ||
| 788 | */ | ||
| 789 | if (task->tf_in_flags.all == 0) { | ||
| 790 | task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS; | ||
| 791 | if (drive->addressing == 1) | ||
| 792 | task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS << 8); | ||
| 793 | } | ||
| 794 | |||
| 795 | /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ | ||
| 796 | if (IDE_CONTROL_REG) | ||
| 797 | /* clear nIEN */ | ||
| 798 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | ||
| 799 | SELECT_MASK(drive, 0); | ||
| 800 | |||
| 801 | if (task->tf_out_flags.b.data) { | ||
| 802 | u16 data = taskfile->data + (hobfile->data << 8); | ||
| 803 | hwif->OUTW(data, IDE_DATA_REG); | ||
| 804 | } | ||
| 805 | |||
| 806 | /* (ks) send hob registers first */ | ||
| 807 | if (task->tf_out_flags.b.nsector_hob) | ||
| 808 | hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); | ||
| 809 | if (task->tf_out_flags.b.sector_hob) | ||
| 810 | hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); | ||
| 811 | if (task->tf_out_flags.b.lcyl_hob) | ||
| 812 | hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); | ||
| 813 | if (task->tf_out_flags.b.hcyl_hob) | ||
| 814 | hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); | ||
| 815 | |||
| 816 | /* (ks) Send now the standard registers */ | ||
| 817 | if (task->tf_out_flags.b.error_feature) | ||
| 818 | hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); | ||
| 819 | /* refers to number of sectors to transfer */ | ||
| 820 | if (task->tf_out_flags.b.nsector) | ||
| 821 | hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); | ||
| 822 | /* refers to sector offset or start sector */ | ||
| 823 | if (task->tf_out_flags.b.sector) | ||
| 824 | hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); | ||
| 825 | if (task->tf_out_flags.b.lcyl) | ||
| 826 | hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); | ||
| 827 | if (task->tf_out_flags.b.hcyl) | ||
| 828 | hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); | ||
| 829 | |||
| 830 | /* | ||
| 831 | * (ks) In the flagged taskfile approch, we will use all specified | ||
| 832 | * registers and the register value will not be changed, except the | ||
| 833 | * select bit (master/slave) in the drive_head register. We must make | ||
| 834 | * sure that the desired drive is selected. | ||
| 835 | */ | ||
| 836 | hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG); | ||
| 837 | switch(task->data_phase) { | ||
| 838 | 853 | ||
| 839 | case TASKFILE_OUT_DMAQ: | 854 | memset(&task, 0, sizeof(task)); |
| 840 | case TASKFILE_OUT_DMA: | 855 | memcpy(&task.tf_array[7], &args[1], 6); |
| 841 | case TASKFILE_IN_DMAQ: | 856 | task.tf.command = args[0]; |
| 842 | case TASKFILE_IN_DMA: | 857 | task.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; |
| 843 | if (!drive->using_dma) | ||
| 844 | break; | ||
| 845 | 858 | ||
| 846 | if (!hwif->dma_setup(drive)) { | 859 | err = ide_no_data_taskfile(drive, &task); |
| 847 | hwif->dma_exec_cmd(drive, taskfile->command); | ||
| 848 | hwif->dma_start(drive); | ||
| 849 | return ide_started; | ||
| 850 | } | ||
| 851 | break; | ||
| 852 | 860 | ||
| 853 | default: | 861 | args[0] = task.tf.command; |
| 854 | if (task->handler == NULL) | 862 | memcpy(&args[1], &task.tf_array[7], 6); |
| 855 | return ide_stopped; | ||
| 856 | 863 | ||
| 857 | /* Issue the command */ | 864 | if (copy_to_user(p, args, 7)) |
| 858 | if (task->prehandler) { | 865 | err = -EFAULT; |
| 859 | hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); | ||
| 860 | ndelay(400); /* FIXME */ | ||
| 861 | return task->prehandler(drive, task->rq); | ||
| 862 | } | ||
| 863 | ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); | ||
| 864 | return ide_started; | ||
| 865 | } | ||
| 866 | 866 | ||
| 867 | return ide_stopped; | 867 | return err; |
| 868 | } | 868 | } |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 54943da6e4e5..c6d4f630e18a 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -424,7 +424,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | |||
| 424 | hwif->reset_poll = tmp_hwif->reset_poll; | 424 | hwif->reset_poll = tmp_hwif->reset_poll; |
| 425 | hwif->pre_reset = tmp_hwif->pre_reset; | 425 | hwif->pre_reset = tmp_hwif->pre_reset; |
| 426 | hwif->resetproc = tmp_hwif->resetproc; | 426 | hwif->resetproc = tmp_hwif->resetproc; |
| 427 | hwif->intrproc = tmp_hwif->intrproc; | ||
| 428 | hwif->maskproc = tmp_hwif->maskproc; | 427 | hwif->maskproc = tmp_hwif->maskproc; |
| 429 | hwif->quirkproc = tmp_hwif->quirkproc; | 428 | hwif->quirkproc = tmp_hwif->quirkproc; |
| 430 | hwif->busproc = tmp_hwif->busproc; | 429 | hwif->busproc = tmp_hwif->busproc; |
| @@ -468,7 +467,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | |||
| 468 | #endif | 467 | #endif |
| 469 | 468 | ||
| 470 | hwif->dma_base = tmp_hwif->dma_base; | 469 | hwif->dma_base = tmp_hwif->dma_base; |
| 471 | hwif->dma_master = tmp_hwif->dma_master; | ||
| 472 | hwif->dma_command = tmp_hwif->dma_command; | 470 | hwif->dma_command = tmp_hwif->dma_command; |
| 473 | hwif->dma_vendor1 = tmp_hwif->dma_vendor1; | 471 | hwif->dma_vendor1 = tmp_hwif->dma_vendor1; |
| 474 | hwif->dma_status = tmp_hwif->dma_status; | 472 | hwif->dma_status = tmp_hwif->dma_status; |
| @@ -602,7 +600,6 @@ void ide_unregister(unsigned int index) | |||
| 602 | (void) ide_release_dma(hwif); | 600 | (void) ide_release_dma(hwif); |
| 603 | 601 | ||
| 604 | hwif->dma_base = 0; | 602 | hwif->dma_base = 0; |
| 605 | hwif->dma_master = 0; | ||
| 606 | hwif->dma_command = 0; | 603 | hwif->dma_command = 0; |
| 607 | hwif->dma_vendor1 = 0; | 604 | hwif->dma_vendor1 = 0; |
| 608 | hwif->dma_status = 0; | 605 | hwif->dma_status = 0; |
| @@ -854,8 +851,7 @@ int set_using_dma(ide_drive_t *drive, int arg) | |||
| 854 | err = 0; | 851 | err = 0; |
| 855 | 852 | ||
| 856 | if (arg) { | 853 | if (arg) { |
| 857 | hwif->dma_off_quietly(drive); | 854 | if (ide_set_dma(drive)) |
| 858 | if (ide_set_dma(drive) || hwif->ide_dma_on(drive)) | ||
| 859 | err = -EIO; | 855 | err = -EIO; |
| 860 | } else | 856 | } else |
| 861 | ide_dma_off(drive); | 857 | ide_dma_off(drive); |
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index a4ce3ba15d61..a4d0d4ca73d0 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c | |||
| @@ -198,8 +198,6 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 198 | 198 | ||
| 199 | break; | 199 | break; |
| 200 | #endif | 200 | #endif |
| 201 | default: | ||
| 202 | return; | ||
| 203 | } | 201 | } |
| 204 | 202 | ||
| 205 | au_writel(mem_sttime,MEM_STTIME2); | 203 | au_writel(mem_sttime,MEM_STTIME2); |
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index 44268504ae43..7f4d1857d555 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c | |||
| @@ -202,6 +202,7 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
| 202 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, | 202 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, |
| 203 | .host_flags = IDE_HFLAG_SERIALIZE | | 203 | .host_flags = IDE_HFLAG_SERIALIZE | |
| 204 | IDE_HFLAG_NO_ATAPI_DMA | | 204 | IDE_HFLAG_NO_ATAPI_DMA | |
| 205 | IDE_HFLAG_ABUSE_SET_DMA_MODE | | ||
| 205 | IDE_HFLAG_OFF_BOARD, | 206 | IDE_HFLAG_OFF_BOARD, |
| 206 | .pio_mask = ATA_PIO4, | 207 | .pio_mask = ATA_PIO4, |
| 207 | .mwdma_mask = ATA_MWDMA2, | 208 | .mwdma_mask = ATA_MWDMA2, |
| @@ -211,6 +212,7 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
| 211 | .init_chipset = init_chipset_aec62xx, | 212 | .init_chipset = init_chipset_aec62xx, |
| 212 | .init_hwif = init_hwif_aec62xx, | 213 | .init_hwif = init_hwif_aec62xx, |
| 213 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA | | 214 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA | |
| 215 | IDE_HFLAG_ABUSE_SET_DMA_MODE | | ||
| 214 | IDE_HFLAG_OFF_BOARD, | 216 | IDE_HFLAG_OFF_BOARD, |
| 215 | .pio_mask = ATA_PIO4, | 217 | .pio_mask = ATA_PIO4, |
| 216 | .mwdma_mask = ATA_MWDMA2, | 218 | .mwdma_mask = ATA_MWDMA2, |
| @@ -220,7 +222,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
| 220 | .init_chipset = init_chipset_aec62xx, | 222 | .init_chipset = init_chipset_aec62xx, |
| 221 | .init_hwif = init_hwif_aec62xx, | 223 | .init_hwif = init_hwif_aec62xx, |
| 222 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, | 224 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, |
| 223 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA, | 225 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | |
| 226 | IDE_HFLAG_ABUSE_SET_DMA_MODE, | ||
| 224 | .pio_mask = ATA_PIO4, | 227 | .pio_mask = ATA_PIO4, |
| 225 | .mwdma_mask = ATA_MWDMA2, | 228 | .mwdma_mask = ATA_MWDMA2, |
| 226 | .udma_mask = ATA_UDMA4, | 229 | .udma_mask = ATA_UDMA4, |
| @@ -228,7 +231,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
| 228 | .name = "AEC6280", | 231 | .name = "AEC6280", |
| 229 | .init_chipset = init_chipset_aec62xx, | 232 | .init_chipset = init_chipset_aec62xx, |
| 230 | .init_hwif = init_hwif_aec62xx, | 233 | .init_hwif = init_hwif_aec62xx, |
| 231 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, | 234 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | |
| 235 | IDE_HFLAG_ABUSE_SET_DMA_MODE | | ||
| 236 | IDE_HFLAG_OFF_BOARD, | ||
| 232 | .pio_mask = ATA_PIO4, | 237 | .pio_mask = ATA_PIO4, |
| 233 | .mwdma_mask = ATA_MWDMA2, | 238 | .mwdma_mask = ATA_MWDMA2, |
| 234 | .udma_mask = ATA_UDMA5, | 239 | .udma_mask = ATA_UDMA5, |
| @@ -237,7 +242,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
| 237 | .init_chipset = init_chipset_aec62xx, | 242 | .init_chipset = init_chipset_aec62xx, |
| 238 | .init_hwif = init_hwif_aec62xx, | 243 | .init_hwif = init_hwif_aec62xx, |
| 239 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, | 244 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, |
| 240 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, | 245 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | |
| 246 | IDE_HFLAG_ABUSE_SET_DMA_MODE | | ||
| 247 | IDE_HFLAG_OFF_BOARD, | ||
| 241 | .pio_mask = ATA_PIO4, | 248 | .pio_mask = ATA_PIO4, |
| 242 | .mwdma_mask = ATA_MWDMA2, | 249 | .mwdma_mask = ATA_MWDMA2, |
| 243 | .udma_mask = ATA_UDMA5, | 250 | .udma_mask = ATA_UDMA5, |
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index ce293936af4b..49aa82e412b6 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c | |||
| @@ -402,9 +402,6 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 402 | u8 tmpbyte = 0x00; | 402 | u8 tmpbyte = 0x00; |
| 403 | int m5229_udma = (hwif->channel) ? 0x57 : 0x56; | 403 | int m5229_udma = (hwif->channel) ? 0x57 : 0x56; |
| 404 | 404 | ||
| 405 | if (speed < XFER_PIO_0) | ||
| 406 | return; | ||
| 407 | |||
| 408 | if (speed == XFER_UDMA_6) | 405 | if (speed == XFER_UDMA_6) |
| 409 | speed1 = 0x47; | 406 | speed1 = 0x47; |
| 410 | 407 | ||
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 8d4125ec252c..cee51fdafcf6 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
| @@ -266,6 +266,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) | |||
| 266 | #define IDE_HFLAGS_AMD \ | 266 | #define IDE_HFLAGS_AMD \ |
| 267 | (IDE_HFLAG_PIO_NO_BLACKLIST | \ | 267 | (IDE_HFLAG_PIO_NO_BLACKLIST | \ |
| 268 | IDE_HFLAG_PIO_NO_DOWNGRADE | \ | 268 | IDE_HFLAG_PIO_NO_DOWNGRADE | \ |
| 269 | IDE_HFLAG_ABUSE_SET_DMA_MODE | \ | ||
| 269 | IDE_HFLAG_POST_SET_MODE | \ | 270 | IDE_HFLAG_POST_SET_MODE | \ |
| 270 | IDE_HFLAG_IO_32BIT | \ | 271 | IDE_HFLAG_IO_32BIT | \ |
| 271 | IDE_HFLAG_UNMASK_IRQS | \ | 272 | IDE_HFLAG_UNMASK_IRQS | \ |
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index ef8e0164ef7a..5ae26564fb72 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c | |||
| @@ -133,9 +133,6 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 133 | u32 tmp32; | 133 | u32 tmp32; |
| 134 | u16 tmp16; | 134 | u16 tmp16; |
| 135 | 135 | ||
| 136 | if (speed < XFER_MW_DMA_0) | ||
| 137 | return; | ||
| 138 | |||
| 139 | spin_lock_irqsave(&atiixp_lock, flags); | 136 | spin_lock_irqsave(&atiixp_lock, flags); |
| 140 | 137 | ||
| 141 | save_mdma_mode[drive->dn] = 0; | 138 | save_mdma_mode[drive->dn] = 0; |
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index bc553337b1be..0b1e9479f019 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c | |||
| @@ -322,8 +322,6 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 322 | case XFER_MW_DMA_0: | 322 | case XFER_MW_DMA_0: |
| 323 | program_cycle_times(drive, 480, 215); | 323 | program_cycle_times(drive, 480, 215); |
| 324 | break; | 324 | break; |
| 325 | default: | ||
| 326 | return; | ||
| 327 | } | 325 | } |
| 328 | 326 | ||
| 329 | if (speed >= XFER_SW_DMA_0) | 327 | if (speed >= XFER_SW_DMA_0) |
| @@ -333,14 +331,15 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 333 | static int cmd648_ide_dma_end (ide_drive_t *drive) | 331 | static int cmd648_ide_dma_end (ide_drive_t *drive) |
| 334 | { | 332 | { |
| 335 | ide_hwif_t *hwif = HWIF(drive); | 333 | ide_hwif_t *hwif = HWIF(drive); |
| 334 | unsigned long base = hwif->dma_base - (hwif->channel * 8); | ||
| 336 | int err = __ide_dma_end(drive); | 335 | int err = __ide_dma_end(drive); |
| 337 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : | 336 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : |
| 338 | MRDMODE_INTR_CH0; | 337 | MRDMODE_INTR_CH0; |
| 339 | u8 mrdmode = inb(hwif->dma_master + 0x01); | 338 | u8 mrdmode = inb(base + 1); |
| 340 | 339 | ||
| 341 | /* clear the interrupt bit */ | 340 | /* clear the interrupt bit */ |
| 342 | outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask, | 341 | outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask, |
| 343 | hwif->dma_master + 0x01); | 342 | base + 1); |
| 344 | 343 | ||
| 345 | return err; | 344 | return err; |
| 346 | } | 345 | } |
| @@ -365,10 +364,11 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive) | |||
| 365 | static int cmd648_ide_dma_test_irq (ide_drive_t *drive) | 364 | static int cmd648_ide_dma_test_irq (ide_drive_t *drive) |
| 366 | { | 365 | { |
| 367 | ide_hwif_t *hwif = HWIF(drive); | 366 | ide_hwif_t *hwif = HWIF(drive); |
| 367 | unsigned long base = hwif->dma_base - (hwif->channel * 8); | ||
| 368 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : | 368 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : |
| 369 | MRDMODE_INTR_CH0; | 369 | MRDMODE_INTR_CH0; |
| 370 | u8 dma_stat = inb(hwif->dma_status); | 370 | u8 dma_stat = inb(hwif->dma_status); |
| 371 | u8 mrdmode = inb(hwif->dma_master + 0x01); | 371 | u8 mrdmode = inb(base + 1); |
| 372 | 372 | ||
| 373 | #ifdef DEBUG | 373 | #ifdef DEBUG |
| 374 | printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n", | 374 | printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n", |
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 0466462fd21b..d1a91bcb5b29 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c | |||
| @@ -137,6 +137,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) | |||
| 137 | IDE_HFLAG_CS5520 | \ | 137 | IDE_HFLAG_CS5520 | \ |
| 138 | IDE_HFLAG_VDMA | \ | 138 | IDE_HFLAG_VDMA | \ |
| 139 | IDE_HFLAG_NO_ATAPI_DMA | \ | 139 | IDE_HFLAG_NO_ATAPI_DMA | \ |
| 140 | IDE_HFLAG_ABUSE_SET_DMA_MODE |\ | ||
| 140 | IDE_HFLAG_BOOTABLE, \ | 141 | IDE_HFLAG_BOOTABLE, \ |
| 141 | .pio_mask = ATA_PIO4, \ | 142 | .pio_mask = ATA_PIO4, \ |
| 142 | } | 143 | } |
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 547690395eee..df5966b33460 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c | |||
| @@ -116,8 +116,6 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
| 116 | case XFER_MW_DMA_0: timings = 0x00077771; break; | 116 | case XFER_MW_DMA_0: timings = 0x00077771; break; |
| 117 | case XFER_MW_DMA_1: timings = 0x00012121; break; | 117 | case XFER_MW_DMA_1: timings = 0x00012121; break; |
| 118 | case XFER_MW_DMA_2: timings = 0x00002020; break; | 118 | case XFER_MW_DMA_2: timings = 0x00002020; break; |
| 119 | default: | ||
| 120 | return; | ||
| 121 | } | 119 | } |
| 122 | basereg = CS5530_BASEREG(drive->hwif); | 120 | basereg = CS5530_BASEREG(drive->hwif); |
| 123 | reg = inl(basereg + 4); /* get drive0 config register */ | 121 | reg = inl(basereg + 4); /* get drive0 config register */ |
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c index ddcbeba671e1..50b3d7791f55 100644 --- a/drivers/ide/pci/cs5535.c +++ b/drivers/ide/pci/cs5535.c | |||
| @@ -190,7 +190,7 @@ static const struct ide_port_info cs5535_chipset __devinitdata = { | |||
| 190 | .name = "CS5535", | 190 | .name = "CS5535", |
| 191 | .init_hwif = init_hwif_cs5535, | 191 | .init_hwif = init_hwif_cs5535, |
| 192 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE | | 192 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE | |
| 193 | IDE_HFLAG_BOOTABLE, | 193 | IDE_HFLAG_ABUSE_SET_DMA_MODE | IDE_HFLAG_BOOTABLE, |
| 194 | .pio_mask = ATA_PIO4, | 194 | .pio_mask = ATA_PIO4, |
| 195 | .mwdma_mask = ATA_MWDMA2, | 195 | .mwdma_mask = ATA_MWDMA2, |
| 196 | .udma_mask = ATA_UDMA4, | 196 | .udma_mask = ATA_UDMA4, |
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index ae6307fae4f9..dfba0d13fcd3 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c | |||
| @@ -129,14 +129,18 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) | |||
| 129 | hwif->set_dma_mode = &hpt34x_set_mode; | 129 | hwif->set_dma_mode = &hpt34x_set_mode; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | #define IDE_HFLAGS_HPT34X \ | ||
| 133 | (IDE_HFLAG_NO_ATAPI_DMA | \ | ||
| 134 | IDE_HFLAG_ABUSE_SET_DMA_MODE | \ | ||
| 135 | IDE_HFLAG_NO_AUTODMA) | ||
| 136 | |||
| 132 | static const struct ide_port_info hpt34x_chipsets[] __devinitdata = { | 137 | static const struct ide_port_info hpt34x_chipsets[] __devinitdata = { |
| 133 | { /* 0 */ | 138 | { /* 0 */ |
| 134 | .name = "HPT343", | 139 | .name = "HPT343", |
| 135 | .init_chipset = init_chipset_hpt34x, | 140 | .init_chipset = init_chipset_hpt34x, |
| 136 | .init_hwif = init_hwif_hpt34x, | 141 | .init_hwif = init_hwif_hpt34x, |
| 137 | .extra = 16, | 142 | .extra = 16, |
| 138 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | | 143 | .host_flags = IDE_HFLAGS_HPT34X, |
| 139 | IDE_HFLAG_NO_AUTODMA, | ||
| 140 | .pio_mask = ATA_PIO5, | 144 | .pio_mask = ATA_PIO5, |
| 141 | }, | 145 | }, |
| 142 | { /* 1 */ | 146 | { /* 1 */ |
| @@ -144,9 +148,7 @@ static const struct ide_port_info hpt34x_chipsets[] __devinitdata = { | |||
| 144 | .init_chipset = init_chipset_hpt34x, | 148 | .init_chipset = init_chipset_hpt34x, |
| 145 | .init_hwif = init_hwif_hpt34x, | 149 | .init_hwif = init_hwif_hpt34x, |
| 146 | .extra = 16, | 150 | .extra = 16, |
| 147 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | | 151 | .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_OFF_BOARD, |
| 148 | IDE_HFLAG_NO_AUTODMA | | ||
| 149 | IDE_HFLAG_OFF_BOARD, | ||
| 150 | .pio_mask = ATA_PIO5, | 152 | .pio_mask = ATA_PIO5, |
| 151 | #ifdef CONFIG_HPT34X_AUTODMA | 153 | #ifdef CONFIG_HPT34X_AUTODMA |
| 152 | .swdma_mask = ATA_SWDMA2, | 154 | .swdma_mask = ATA_SWDMA2, |
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 9fce25bdec8a..3777fb8c8043 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/ide/pci/hpt366.c Version 1.22 Dec 4, 2007 | 2 | * linux/drivers/ide/pci/hpt366.c Version 1.30 Dec 12, 2007 |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
| 5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
| @@ -88,7 +88,7 @@ | |||
| 88 | * - rename all the register related variables consistently | 88 | * - rename all the register related variables consistently |
| 89 | * - move all the interrupt twiddling code from the speedproc handlers into | 89 | * - move all the interrupt twiddling code from the speedproc handlers into |
| 90 | * init_hwif_hpt366(), also grouping all the DMA related code together there | 90 | * init_hwif_hpt366(), also grouping all the DMA related code together there |
| 91 | * - merge two HPT37x speedproc handlers, fix the PIO timing register mask and | 91 | * - merge HPT36x/HPT37x speedproc handlers, fix PIO timing register mask and |
| 92 | * separate the UltraDMA and MWDMA masks there to avoid changing PIO timings | 92 | * separate the UltraDMA and MWDMA masks there to avoid changing PIO timings |
| 93 | * when setting an UltraDMA mode | 93 | * when setting an UltraDMA mode |
| 94 | * - fix hpt3xx_tune_drive() to set the PIO mode requested, not always select | 94 | * - fix hpt3xx_tune_drive() to set the PIO mode requested, not always select |
| @@ -458,6 +458,13 @@ enum ata_clock { | |||
| 458 | NUM_ATA_CLOCKS | 458 | NUM_ATA_CLOCKS |
| 459 | }; | 459 | }; |
| 460 | 460 | ||
| 461 | struct hpt_timings { | ||
| 462 | u32 pio_mask; | ||
| 463 | u32 dma_mask; | ||
| 464 | u32 ultra_mask; | ||
| 465 | u32 *clock_table[NUM_ATA_CLOCKS]; | ||
| 466 | }; | ||
| 467 | |||
| 461 | /* | 468 | /* |
| 462 | * Hold all the HighPoint chip information in one place. | 469 | * Hold all the HighPoint chip information in one place. |
| 463 | */ | 470 | */ |
| @@ -468,7 +475,8 @@ struct hpt_info { | |||
| 468 | u8 udma_mask; /* Allowed UltraDMA modes mask. */ | 475 | u8 udma_mask; /* Allowed UltraDMA modes mask. */ |
| 469 | u8 dpll_clk; /* DPLL clock in MHz */ | 476 | u8 dpll_clk; /* DPLL clock in MHz */ |
| 470 | u8 pci_clk; /* PCI clock in MHz */ | 477 | u8 pci_clk; /* PCI clock in MHz */ |
| 471 | u32 **settings; /* Chipset settings table */ | 478 | struct hpt_timings *timings; /* Chipset timing data */ |
| 479 | u8 clock; /* ATA clock selected */ | ||
| 472 | }; | 480 | }; |
| 473 | 481 | ||
| 474 | /* Supported HighPoint chips */ | 482 | /* Supported HighPoint chips */ |
| @@ -486,20 +494,30 @@ enum { | |||
| 486 | HPT371N | 494 | HPT371N |
| 487 | }; | 495 | }; |
| 488 | 496 | ||
| 489 | static u32 *hpt36x_settings[NUM_ATA_CLOCKS] = { | 497 | static struct hpt_timings hpt36x_timings = { |
| 490 | twenty_five_base_hpt36x, | 498 | .pio_mask = 0xc1f8ffff, |
| 491 | thirty_three_base_hpt36x, | 499 | .dma_mask = 0x303800ff, |
| 492 | forty_base_hpt36x, | 500 | .ultra_mask = 0x30070000, |
| 493 | NULL, | 501 | .clock_table = { |
| 494 | NULL | 502 | [ATA_CLOCK_25MHZ] = twenty_five_base_hpt36x, |
| 503 | [ATA_CLOCK_33MHZ] = thirty_three_base_hpt36x, | ||
| 504 | [ATA_CLOCK_40MHZ] = forty_base_hpt36x, | ||
| 505 | [ATA_CLOCK_50MHZ] = NULL, | ||
| 506 | [ATA_CLOCK_66MHZ] = NULL | ||
| 507 | } | ||
| 495 | }; | 508 | }; |
| 496 | 509 | ||
| 497 | static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = { | 510 | static struct hpt_timings hpt37x_timings = { |
| 498 | NULL, | 511 | .pio_mask = 0xcfc3ffff, |
| 499 | thirty_three_base_hpt37x, | 512 | .dma_mask = 0x31c001ff, |
| 500 | NULL, | 513 | .ultra_mask = 0x303c0000, |
| 501 | fifty_base_hpt37x, | 514 | .clock_table = { |
| 502 | sixty_six_base_hpt37x | 515 | [ATA_CLOCK_25MHZ] = NULL, |
| 516 | [ATA_CLOCK_33MHZ] = thirty_three_base_hpt37x, | ||
| 517 | [ATA_CLOCK_40MHZ] = NULL, | ||
| 518 | [ATA_CLOCK_50MHZ] = fifty_base_hpt37x, | ||
| 519 | [ATA_CLOCK_66MHZ] = sixty_six_base_hpt37x | ||
| 520 | } | ||
| 503 | }; | 521 | }; |
| 504 | 522 | ||
| 505 | static const struct hpt_info hpt36x __devinitdata = { | 523 | static const struct hpt_info hpt36x __devinitdata = { |
| @@ -507,7 +525,7 @@ static const struct hpt_info hpt36x __devinitdata = { | |||
| 507 | .chip_type = HPT36x, | 525 | .chip_type = HPT36x, |
| 508 | .udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2, | 526 | .udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2, |
| 509 | .dpll_clk = 0, /* no DPLL */ | 527 | .dpll_clk = 0, /* no DPLL */ |
| 510 | .settings = hpt36x_settings | 528 | .timings = &hpt36x_timings |
| 511 | }; | 529 | }; |
| 512 | 530 | ||
| 513 | static const struct hpt_info hpt370 __devinitdata = { | 531 | static const struct hpt_info hpt370 __devinitdata = { |
| @@ -515,7 +533,7 @@ static const struct hpt_info hpt370 __devinitdata = { | |||
| 515 | .chip_type = HPT370, | 533 | .chip_type = HPT370, |
| 516 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, | 534 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, |
| 517 | .dpll_clk = 48, | 535 | .dpll_clk = 48, |
| 518 | .settings = hpt37x_settings | 536 | .timings = &hpt37x_timings |
| 519 | }; | 537 | }; |
| 520 | 538 | ||
| 521 | static const struct hpt_info hpt370a __devinitdata = { | 539 | static const struct hpt_info hpt370a __devinitdata = { |
| @@ -523,7 +541,7 @@ static const struct hpt_info hpt370a __devinitdata = { | |||
| 523 | .chip_type = HPT370A, | 541 | .chip_type = HPT370A, |
| 524 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, | 542 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, |
| 525 | .dpll_clk = 48, | 543 | .dpll_clk = 48, |
| 526 | .settings = hpt37x_settings | 544 | .timings = &hpt37x_timings |
| 527 | }; | 545 | }; |
| 528 | 546 | ||
| 529 | static const struct hpt_info hpt374 __devinitdata = { | 547 | static const struct hpt_info hpt374 __devinitdata = { |
| @@ -531,7 +549,7 @@ static const struct hpt_info hpt374 __devinitdata = { | |||
| 531 | .chip_type = HPT374, | 549 | .chip_type = HPT374, |
| 532 | .udma_mask = ATA_UDMA5, | 550 | .udma_mask = ATA_UDMA5, |
| 533 | .dpll_clk = 48, | 551 | .dpll_clk = 48, |
| 534 | .settings = hpt37x_settings | 552 | .timings = &hpt37x_timings |
| 535 | }; | 553 | }; |
| 536 | 554 | ||
| 537 | static const struct hpt_info hpt372 __devinitdata = { | 555 | static const struct hpt_info hpt372 __devinitdata = { |
| @@ -539,7 +557,7 @@ static const struct hpt_info hpt372 __devinitdata = { | |||
| 539 | .chip_type = HPT372, | 557 | .chip_type = HPT372, |
| 540 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 558 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
| 541 | .dpll_clk = 55, | 559 | .dpll_clk = 55, |
| 542 | .settings = hpt37x_settings | 560 | .timings = &hpt37x_timings |
| 543 | }; | 561 | }; |
| 544 | 562 | ||
| 545 | static const struct hpt_info hpt372a __devinitdata = { | 563 | static const struct hpt_info hpt372a __devinitdata = { |
| @@ -547,7 +565,7 @@ static const struct hpt_info hpt372a __devinitdata = { | |||
| 547 | .chip_type = HPT372A, | 565 | .chip_type = HPT372A, |
| 548 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 566 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
| 549 | .dpll_clk = 66, | 567 | .dpll_clk = 66, |
| 550 | .settings = hpt37x_settings | 568 | .timings = &hpt37x_timings |
| 551 | }; | 569 | }; |
| 552 | 570 | ||
| 553 | static const struct hpt_info hpt302 __devinitdata = { | 571 | static const struct hpt_info hpt302 __devinitdata = { |
| @@ -555,7 +573,7 @@ static const struct hpt_info hpt302 __devinitdata = { | |||
| 555 | .chip_type = HPT302, | 573 | .chip_type = HPT302, |
| 556 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 574 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
| 557 | .dpll_clk = 66, | 575 | .dpll_clk = 66, |
| 558 | .settings = hpt37x_settings | 576 | .timings = &hpt37x_timings |
| 559 | }; | 577 | }; |
| 560 | 578 | ||
| 561 | static const struct hpt_info hpt371 __devinitdata = { | 579 | static const struct hpt_info hpt371 __devinitdata = { |
| @@ -563,7 +581,7 @@ static const struct hpt_info hpt371 __devinitdata = { | |||
| 563 | .chip_type = HPT371, | 581 | .chip_type = HPT371, |
| 564 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 582 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
| 565 | .dpll_clk = 66, | 583 | .dpll_clk = 66, |
| 566 | .settings = hpt37x_settings | 584 | .timings = &hpt37x_timings |
| 567 | }; | 585 | }; |
| 568 | 586 | ||
| 569 | static const struct hpt_info hpt372n __devinitdata = { | 587 | static const struct hpt_info hpt372n __devinitdata = { |
| @@ -571,7 +589,7 @@ static const struct hpt_info hpt372n __devinitdata = { | |||
| 571 | .chip_type = HPT372N, | 589 | .chip_type = HPT372N, |
| 572 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 590 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
| 573 | .dpll_clk = 77, | 591 | .dpll_clk = 77, |
| 574 | .settings = hpt37x_settings | 592 | .timings = &hpt37x_timings |
| 575 | }; | 593 | }; |
| 576 | 594 | ||
| 577 | static const struct hpt_info hpt302n __devinitdata = { | 595 | static const struct hpt_info hpt302n __devinitdata = { |
| @@ -579,7 +597,7 @@ static const struct hpt_info hpt302n __devinitdata = { | |||
| 579 | .chip_type = HPT302N, | 597 | .chip_type = HPT302N, |
| 580 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 598 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
| 581 | .dpll_clk = 77, | 599 | .dpll_clk = 77, |
| 582 | .settings = hpt37x_settings | 600 | .timings = &hpt37x_timings |
| 583 | }; | 601 | }; |
| 584 | 602 | ||
| 585 | static const struct hpt_info hpt371n __devinitdata = { | 603 | static const struct hpt_info hpt371n __devinitdata = { |
| @@ -587,7 +605,7 @@ static const struct hpt_info hpt371n __devinitdata = { | |||
| 587 | .chip_type = HPT371N, | 605 | .chip_type = HPT371N, |
| 588 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 606 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
| 589 | .dpll_clk = 77, | 607 | .dpll_clk = 77, |
| 590 | .settings = hpt37x_settings | 608 | .timings = &hpt37x_timings |
| 591 | }; | 609 | }; |
| 592 | 610 | ||
| 593 | static int check_in_drive_list(ide_drive_t *drive, const char **list) | 611 | static int check_in_drive_list(ide_drive_t *drive, const char **list) |
| @@ -675,71 +693,33 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info) | |||
| 675 | for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++) | 693 | for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++) |
| 676 | if (xfer_speeds[i] == speed) | 694 | if (xfer_speeds[i] == speed) |
| 677 | break; | 695 | break; |
| 678 | /* | 696 | |
| 679 | * NOTE: info->settings only points to the pointer | 697 | return info->timings->clock_table[info->clock][i]; |
| 680 | * to the list of the actual register values | ||
| 681 | */ | ||
| 682 | return (*info->settings)[i]; | ||
| 683 | } | 698 | } |
| 684 | 699 | ||
| 685 | static void hpt36x_set_mode(ide_drive_t *drive, const u8 speed) | 700 | static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed) |
| 686 | { | 701 | { |
| 687 | ide_hwif_t *hwif = HWIF(drive); | 702 | struct pci_dev *dev = HWIF(drive)->pci_dev; |
| 688 | struct pci_dev *dev = hwif->pci_dev; | ||
| 689 | struct hpt_info *info = pci_get_drvdata(dev); | 703 | struct hpt_info *info = pci_get_drvdata(dev); |
| 690 | u8 itr_addr = drive->dn ? 0x44 : 0x40; | 704 | struct hpt_timings *t = info->timings; |
| 705 | u8 itr_addr = 0x40 + (drive->dn * 4); | ||
| 691 | u32 old_itr = 0; | 706 | u32 old_itr = 0; |
| 692 | u32 itr_mask, new_itr; | 707 | u32 new_itr = get_speed_setting(speed, info); |
| 693 | 708 | u32 itr_mask = speed < XFER_MW_DMA_0 ? t->pio_mask : | |
| 694 | itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 : | 709 | (speed < XFER_UDMA_0 ? t->dma_mask : |
| 695 | (speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff); | 710 | t->ultra_mask); |
| 696 | |||
| 697 | new_itr = get_speed_setting(speed, info); | ||
| 698 | 711 | ||
| 712 | pci_read_config_dword(dev, itr_addr, &old_itr); | ||
| 713 | new_itr = (old_itr & ~itr_mask) | (new_itr & itr_mask); | ||
| 699 | /* | 714 | /* |
| 700 | * Disable on-chip PIO FIFO/buffer (and PIO MST mode as well) | 715 | * Disable on-chip PIO FIFO/buffer (and PIO MST mode as well) |
| 701 | * to avoid problems handling I/O errors later | 716 | * to avoid problems handling I/O errors later |
| 702 | */ | 717 | */ |
| 703 | pci_read_config_dword(dev, itr_addr, &old_itr); | ||
| 704 | new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask); | ||
| 705 | new_itr &= ~0xc0000000; | 718 | new_itr &= ~0xc0000000; |
| 706 | 719 | ||
| 707 | pci_write_config_dword(dev, itr_addr, new_itr); | 720 | pci_write_config_dword(dev, itr_addr, new_itr); |
| 708 | } | 721 | } |
| 709 | 722 | ||
| 710 | static void hpt37x_set_mode(ide_drive_t *drive, const u8 speed) | ||
| 711 | { | ||
| 712 | ide_hwif_t *hwif = HWIF(drive); | ||
| 713 | struct pci_dev *dev = hwif->pci_dev; | ||
| 714 | struct hpt_info *info = pci_get_drvdata(dev); | ||
| 715 | u8 itr_addr = 0x40 + (drive->dn * 4); | ||
| 716 | u32 old_itr = 0; | ||
| 717 | u32 itr_mask, new_itr; | ||
| 718 | |||
| 719 | itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 : | ||
| 720 | (speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff); | ||
| 721 | |||
| 722 | new_itr = get_speed_setting(speed, info); | ||
| 723 | |||
| 724 | pci_read_config_dword(dev, itr_addr, &old_itr); | ||
| 725 | new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask); | ||
| 726 | |||
| 727 | if (speed < XFER_MW_DMA_0) | ||
| 728 | new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ | ||
| 729 | pci_write_config_dword(dev, itr_addr, new_itr); | ||
| 730 | } | ||
| 731 | |||
| 732 | static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed) | ||
| 733 | { | ||
| 734 | ide_hwif_t *hwif = HWIF(drive); | ||
| 735 | struct hpt_info *info = pci_get_drvdata(hwif->pci_dev); | ||
| 736 | |||
| 737 | if (info->chip_type >= HPT370) | ||
| 738 | hpt37x_set_mode(drive, speed); | ||
| 739 | else /* hpt368: hpt_minimum_revision(dev, 2) */ | ||
| 740 | hpt36x_set_mode(drive, speed); | ||
| 741 | } | ||
| 742 | |||
| 743 | static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | 723 | static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio) |
| 744 | { | 724 | { |
| 745 | hpt3xx_set_mode(drive, XFER_PIO_0 + pio); | 725 | hpt3xx_set_mode(drive, XFER_PIO_0 + pio); |
| @@ -756,15 +736,6 @@ static int hpt3xx_quirkproc(ide_drive_t *drive) | |||
| 756 | return 0; | 736 | return 0; |
| 757 | } | 737 | } |
| 758 | 738 | ||
| 759 | static void hpt3xx_intrproc(ide_drive_t *drive) | ||
| 760 | { | ||
| 761 | if (drive->quirk_list) | ||
| 762 | return; | ||
| 763 | |||
| 764 | /* drives in the quirk_list may not like intr setups/cleanups */ | ||
| 765 | outb(drive->ctl | 2, IDE_CONTROL_REG); | ||
| 766 | } | ||
| 767 | |||
| 768 | static void hpt3xx_maskproc(ide_drive_t *drive, int mask) | 739 | static void hpt3xx_maskproc(ide_drive_t *drive, int mask) |
| 769 | { | 740 | { |
| 770 | ide_hwif_t *hwif = HWIF(drive); | 741 | ide_hwif_t *hwif = HWIF(drive); |
| @@ -914,32 +885,33 @@ static int hpt374_ide_dma_end(ide_drive_t *drive) | |||
| 914 | 885 | ||
| 915 | static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode) | 886 | static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode) |
| 916 | { | 887 | { |
| 917 | u8 scr2 = inb(hwif->dma_master + 0x7b); | 888 | unsigned long base = hwif->extra_base; |
| 889 | u8 scr2 = inb(base + 0x6b); | ||
| 918 | 890 | ||
| 919 | if ((scr2 & 0x7f) == mode) | 891 | if ((scr2 & 0x7f) == mode) |
| 920 | return; | 892 | return; |
| 921 | 893 | ||
| 922 | /* Tristate the bus */ | 894 | /* Tristate the bus */ |
| 923 | outb(0x80, hwif->dma_master + 0x73); | 895 | outb(0x80, base + 0x63); |
| 924 | outb(0x80, hwif->dma_master + 0x77); | 896 | outb(0x80, base + 0x67); |
| 925 | 897 | ||
| 926 | /* Switch clock and reset channels */ | 898 | /* Switch clock and reset channels */ |
| 927 | outb(mode, hwif->dma_master + 0x7b); | 899 | outb(mode, base + 0x6b); |
| 928 | outb(0xc0, hwif->dma_master + 0x79); | 900 | outb(0xc0, base + 0x69); |
| 929 | 901 | ||
| 930 | /* | 902 | /* |
| 931 | * Reset the state machines. | 903 | * Reset the state machines. |
| 932 | * NOTE: avoid accidentally enabling the disabled channels. | 904 | * NOTE: avoid accidentally enabling the disabled channels. |
| 933 | */ | 905 | */ |
| 934 | outb(inb(hwif->dma_master + 0x70) | 0x32, hwif->dma_master + 0x70); | 906 | outb(inb(base + 0x60) | 0x32, base + 0x60); |
| 935 | outb(inb(hwif->dma_master + 0x74) | 0x32, hwif->dma_master + 0x74); | 907 | outb(inb(base + 0x64) | 0x32, base + 0x64); |
| 936 | 908 | ||
| 937 | /* Complete reset */ | 909 | /* Complete reset */ |
| 938 | outb(0x00, hwif->dma_master + 0x79); | 910 | outb(0x00, base + 0x69); |
| 939 | 911 | ||
| 940 | /* Reconnect channels to bus */ | 912 | /* Reconnect channels to bus */ |
| 941 | outb(0x00, hwif->dma_master + 0x73); | 913 | outb(0x00, base + 0x63); |
| 942 | outb(0x00, hwif->dma_master + 0x77); | 914 | outb(0x00, base + 0x67); |
| 943 | } | 915 | } |
| 944 | 916 | ||
| 945 | /** | 917 | /** |
| @@ -1210,7 +1182,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha | |||
| 1210 | * We also don't like using the DPLL because this causes glitches | 1182 | * We also don't like using the DPLL because this causes glitches |
| 1211 | * on PRST-/SRST- when the state engine gets reset... | 1183 | * on PRST-/SRST- when the state engine gets reset... |
| 1212 | */ | 1184 | */ |
| 1213 | if (chip_type >= HPT374 || info->settings[clock] == NULL) { | 1185 | if (chip_type >= HPT374 || info->timings->clock_table[clock] == NULL) { |
| 1214 | u16 f_low, delta = pci_clk < 50 ? 2 : 4; | 1186 | u16 f_low, delta = pci_clk < 50 ? 2 : 4; |
| 1215 | int adjust; | 1187 | int adjust; |
| 1216 | 1188 | ||
| @@ -1226,7 +1198,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha | |||
| 1226 | clock = ATA_CLOCK_50MHZ; | 1198 | clock = ATA_CLOCK_50MHZ; |
| 1227 | } | 1199 | } |
| 1228 | 1200 | ||
| 1229 | if (info->settings[clock] == NULL) { | 1201 | if (info->timings->clock_table[clock] == NULL) { |
| 1230 | printk(KERN_ERR "%s: unknown bus timing!\n", name); | 1202 | printk(KERN_ERR "%s: unknown bus timing!\n", name); |
| 1231 | kfree(info); | 1203 | kfree(info); |
| 1232 | return -EIO; | 1204 | return -EIO; |
| @@ -1267,15 +1239,10 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha | |||
| 1267 | printk("%s: using %d MHz PCI clock\n", name, pci_clk); | 1239 | printk("%s: using %d MHz PCI clock\n", name, pci_clk); |
| 1268 | } | 1240 | } |
| 1269 | 1241 | ||
| 1270 | /* | ||
| 1271 | * Advance the table pointer to a slot which points to the list | ||
| 1272 | * of the register values settings matching the clock being used. | ||
| 1273 | */ | ||
| 1274 | info->settings += clock; | ||
| 1275 | |||
| 1276 | /* Store the clock frequencies. */ | 1242 | /* Store the clock frequencies. */ |
| 1277 | info->dpll_clk = dpll_clk; | 1243 | info->dpll_clk = dpll_clk; |
| 1278 | info->pci_clk = pci_clk; | 1244 | info->pci_clk = pci_clk; |
| 1245 | info->clock = clock; | ||
| 1279 | 1246 | ||
| 1280 | /* Point to this chip's own instance of the hpt_info structure. */ | 1247 | /* Point to this chip's own instance of the hpt_info structure. */ |
| 1281 | pci_set_drvdata(dev, info); | 1248 | pci_set_drvdata(dev, info); |
| @@ -1320,8 +1287,8 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) | |||
| 1320 | 1287 | ||
| 1321 | hwif->set_pio_mode = &hpt3xx_set_pio_mode; | 1288 | hwif->set_pio_mode = &hpt3xx_set_pio_mode; |
| 1322 | hwif->set_dma_mode = &hpt3xx_set_mode; | 1289 | hwif->set_dma_mode = &hpt3xx_set_mode; |
| 1290 | |||
| 1323 | hwif->quirkproc = &hpt3xx_quirkproc; | 1291 | hwif->quirkproc = &hpt3xx_quirkproc; |
| 1324 | hwif->intrproc = &hpt3xx_intrproc; | ||
| 1325 | hwif->maskproc = &hpt3xx_maskproc; | 1292 | hwif->maskproc = &hpt3xx_maskproc; |
| 1326 | hwif->busproc = &hpt3xx_busproc; | 1293 | hwif->busproc = &hpt3xx_busproc; |
| 1327 | 1294 | ||
| @@ -1494,6 +1461,11 @@ static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2) | |||
| 1494 | return 0; | 1461 | return 0; |
| 1495 | } | 1462 | } |
| 1496 | 1463 | ||
| 1464 | #define IDE_HFLAGS_HPT3XX \ | ||
| 1465 | (IDE_HFLAG_NO_ATAPI_DMA | \ | ||
| 1466 | IDE_HFLAG_ABUSE_SET_DMA_MODE | \ | ||
| 1467 | IDE_HFLAG_OFF_BOARD) | ||
| 1468 | |||
| 1497 | static const struct ide_port_info hpt366_chipsets[] __devinitdata = { | 1469 | static const struct ide_port_info hpt366_chipsets[] __devinitdata = { |
| 1498 | { /* 0 */ | 1470 | { /* 0 */ |
| 1499 | .name = "HPT36x", | 1471 | .name = "HPT36x", |
| @@ -1508,9 +1480,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = { | |||
| 1508 | */ | 1480 | */ |
| 1509 | .enablebits = {{0x50,0x10,0x10}, {0x54,0x04,0x04}}, | 1481 | .enablebits = {{0x50,0x10,0x10}, {0x54,0x04,0x04}}, |
| 1510 | .extra = 240, | 1482 | .extra = 240, |
| 1511 | .host_flags = IDE_HFLAG_SINGLE | | 1483 | .host_flags = IDE_HFLAGS_HPT3XX | IDE_HFLAG_SINGLE, |
| 1512 | IDE_HFLAG_NO_ATAPI_DMA | | ||
| 1513 | IDE_HFLAG_OFF_BOARD, | ||
| 1514 | .pio_mask = ATA_PIO4, | 1484 | .pio_mask = ATA_PIO4, |
| 1515 | .mwdma_mask = ATA_MWDMA2, | 1485 | .mwdma_mask = ATA_MWDMA2, |
| 1516 | },{ /* 1 */ | 1486 | },{ /* 1 */ |
| @@ -1520,7 +1490,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = { | |||
| 1520 | .init_dma = init_dma_hpt366, | 1490 | .init_dma = init_dma_hpt366, |
| 1521 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, | 1491 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, |
| 1522 | .extra = 240, | 1492 | .extra = 240, |
| 1523 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, | 1493 | .host_flags = IDE_HFLAGS_HPT3XX, |
| 1524 | .pio_mask = ATA_PIO4, | 1494 | .pio_mask = ATA_PIO4, |
| 1525 | .mwdma_mask = ATA_MWDMA2, | 1495 | .mwdma_mask = ATA_MWDMA2, |
| 1526 | },{ /* 2 */ | 1496 | },{ /* 2 */ |
| @@ -1530,7 +1500,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = { | |||
| 1530 | .init_dma = init_dma_hpt366, | 1500 | .init_dma = init_dma_hpt366, |
| 1531 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, | 1501 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, |
| 1532 | .extra = 240, | 1502 | .extra = 240, |
| 1533 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, | 1503 | .host_flags = IDE_HFLAGS_HPT3XX, |
| 1534 | .pio_mask = ATA_PIO4, | 1504 | .pio_mask = ATA_PIO4, |
| 1535 | .mwdma_mask = ATA_MWDMA2, | 1505 | .mwdma_mask = ATA_MWDMA2, |
| 1536 | },{ /* 3 */ | 1506 | },{ /* 3 */ |
| @@ -1540,7 +1510,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = { | |||
| 1540 | .init_dma = init_dma_hpt366, | 1510 | .init_dma = init_dma_hpt366, |
| 1541 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, | 1511 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, |
| 1542 | .extra = 240, | 1512 | .extra = 240, |
| 1543 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, | 1513 | .host_flags = IDE_HFLAGS_HPT3XX, |
| 1544 | .pio_mask = ATA_PIO4, | 1514 | .pio_mask = ATA_PIO4, |
| 1545 | .mwdma_mask = ATA_MWDMA2, | 1515 | .mwdma_mask = ATA_MWDMA2, |
| 1546 | },{ /* 4 */ | 1516 | },{ /* 4 */ |
| @@ -1551,7 +1521,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = { | |||
| 1551 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, | 1521 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, |
| 1552 | .udma_mask = ATA_UDMA5, | 1522 | .udma_mask = ATA_UDMA5, |
| 1553 | .extra = 240, | 1523 | .extra = 240, |
| 1554 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, | 1524 | .host_flags = IDE_HFLAGS_HPT3XX, |
| 1555 | .pio_mask = ATA_PIO4, | 1525 | .pio_mask = ATA_PIO4, |
| 1556 | .mwdma_mask = ATA_MWDMA2, | 1526 | .mwdma_mask = ATA_MWDMA2, |
| 1557 | },{ /* 5 */ | 1527 | },{ /* 5 */ |
| @@ -1561,7 +1531,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = { | |||
| 1561 | .init_dma = init_dma_hpt366, | 1531 | .init_dma = init_dma_hpt366, |
| 1562 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, | 1532 | .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, |
| 1563 | .extra = 240, | 1533 | .extra = 240, |
| 1564 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, | 1534 | .host_flags = IDE_HFLAGS_HPT3XX, |
| 1565 | .pio_mask = ATA_PIO4, | 1535 | .pio_mask = ATA_PIO4, |
| 1566 | .mwdma_mask = ATA_MWDMA2, | 1536 | .mwdma_mask = ATA_MWDMA2, |
| 1567 | } | 1537 | } |
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c index 90b52ed37bfc..2a0f45c4f4c4 100644 --- a/drivers/ide/pci/it8213.c +++ b/drivers/ide/pci/it8213.c | |||
| @@ -101,24 +101,11 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 101 | pci_read_config_byte(dev, 0x54, ®54); | 101 | pci_read_config_byte(dev, 0x54, ®54); |
| 102 | pci_read_config_byte(dev, 0x55, ®55); | 102 | pci_read_config_byte(dev, 0x55, ®55); |
| 103 | 103 | ||
| 104 | switch(speed) { | ||
| 105 | case XFER_UDMA_6: | ||
| 106 | case XFER_UDMA_4: | ||
| 107 | case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; | ||
| 108 | case XFER_UDMA_5: | ||
| 109 | case XFER_UDMA_3: | ||
| 110 | case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; | ||
| 111 | case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; | ||
| 112 | break; | ||
| 113 | case XFER_MW_DMA_2: | ||
| 114 | case XFER_MW_DMA_1: | ||
| 115 | case XFER_SW_DMA_2: | ||
| 116 | break; | ||
| 117 | default: | ||
| 118 | return; | ||
| 119 | } | ||
| 120 | |||
| 121 | if (speed >= XFER_UDMA_0) { | 104 | if (speed >= XFER_UDMA_0) { |
| 105 | u8 udma = speed - XFER_UDMA_0; | ||
| 106 | |||
| 107 | u_speed = min_t(u8, 2 - (udma & 1), udma) << (drive->dn * 4); | ||
| 108 | |||
| 122 | if (!(reg48 & u_flag)) | 109 | if (!(reg48 & u_flag)) |
| 123 | pci_write_config_byte(dev, 0x48, reg48 | u_flag); | 110 | pci_write_config_byte(dev, 0x48, reg48 | u_flag); |
| 124 | if (speed >= XFER_UDMA_5) { | 111 | if (speed >= XFER_UDMA_5) { |
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 2b4f44e45a1a..ef4a99b99d1f 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c | |||
| @@ -146,7 +146,7 @@ static struct udma_timing { | |||
| 146 | { 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */ | 146 | { 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */ |
| 147 | }; | 147 | }; |
| 148 | 148 | ||
| 149 | static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed) | 149 | static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed) |
| 150 | { | 150 | { |
| 151 | ide_hwif_t *hwif = HWIF(drive); | 151 | ide_hwif_t *hwif = HWIF(drive); |
| 152 | u8 adj = (drive->dn & 1) ? 0x08 : 0x00; | 152 | u8 adj = (drive->dn & 1) ? 0x08 : 0x00; |
| @@ -162,45 +162,18 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed) | |||
| 162 | if (max_dma_rate(hwif->pci_dev) == 4) { | 162 | if (max_dma_rate(hwif->pci_dev) == 4) { |
| 163 | u8 mode = speed & 0x07; | 163 | u8 mode = speed & 0x07; |
| 164 | 164 | ||
| 165 | switch (speed) { | 165 | if (speed >= XFER_UDMA_0) { |
| 166 | case XFER_UDMA_6: | 166 | set_indexed_reg(hwif, 0x10 + adj, |
| 167 | case XFER_UDMA_5: | 167 | udma_timings[mode].reg10); |
| 168 | case XFER_UDMA_4: | 168 | set_indexed_reg(hwif, 0x11 + adj, |
| 169 | case XFER_UDMA_3: | 169 | udma_timings[mode].reg11); |
| 170 | case XFER_UDMA_2: | 170 | set_indexed_reg(hwif, 0x12 + adj, |
| 171 | case XFER_UDMA_1: | 171 | udma_timings[mode].reg12); |
| 172 | case XFER_UDMA_0: | 172 | } else { |
| 173 | set_indexed_reg(hwif, 0x10 + adj, | 173 | set_indexed_reg(hwif, 0x0e + adj, |
| 174 | udma_timings[mode].reg10); | 174 | mwdma_timings[mode].reg0e); |
| 175 | set_indexed_reg(hwif, 0x11 + adj, | 175 | set_indexed_reg(hwif, 0x0f + adj, |
| 176 | udma_timings[mode].reg11); | 176 | mwdma_timings[mode].reg0f); |
| 177 | set_indexed_reg(hwif, 0x12 + adj, | ||
| 178 | udma_timings[mode].reg12); | ||
| 179 | break; | ||
| 180 | |||
| 181 | case XFER_MW_DMA_2: | ||
| 182 | case XFER_MW_DMA_1: | ||
| 183 | case XFER_MW_DMA_0: | ||
| 184 | set_indexed_reg(hwif, 0x0e + adj, | ||
| 185 | mwdma_timings[mode].reg0e); | ||
| 186 | set_indexed_reg(hwif, 0x0f + adj, | ||
| 187 | mwdma_timings[mode].reg0f); | ||
| 188 | break; | ||
| 189 | case XFER_PIO_4: | ||
| 190 | case XFER_PIO_3: | ||
| 191 | case XFER_PIO_2: | ||
| 192 | case XFER_PIO_1: | ||
| 193 | case XFER_PIO_0: | ||
| 194 | set_indexed_reg(hwif, 0x0c + adj, | ||
| 195 | pio_timings[mode].reg0c); | ||
| 196 | set_indexed_reg(hwif, 0x0d + adj, | ||
| 197 | pio_timings[mode].reg0d); | ||
| 198 | set_indexed_reg(hwif, 0x13 + adj, | ||
| 199 | pio_timings[mode].reg13); | ||
| 200 | break; | ||
| 201 | default: | ||
| 202 | printk(KERN_ERR "pdc202xx_new: " | ||
| 203 | "Unknown speed %d ignored\n", speed); | ||
| 204 | } | 177 | } |
| 205 | } else if (speed == XFER_UDMA_2) { | 178 | } else if (speed == XFER_UDMA_2) { |
| 206 | /* Set tHOLD bit to 0 if using UDMA mode 2 */ | 179 | /* Set tHOLD bit to 0 if using UDMA mode 2 */ |
| @@ -212,7 +185,14 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed) | |||
| 212 | 185 | ||
| 213 | static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio) | 186 | static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio) |
| 214 | { | 187 | { |
| 215 | pdcnew_set_mode(drive, XFER_PIO_0 + pio); | 188 | ide_hwif_t *hwif = drive->hwif; |
| 189 | u8 adj = (drive->dn & 1) ? 0x08 : 0x00; | ||
| 190 | |||
| 191 | if (max_dma_rate(hwif->pci_dev) == 4) { | ||
| 192 | set_indexed_reg(hwif, 0x0c + adj, pio_timings[pio].reg0c); | ||
| 193 | set_indexed_reg(hwif, 0x0d + adj, pio_timings[pio].reg0d); | ||
| 194 | set_indexed_reg(hwif, 0x13 + adj, pio_timings[pio].reg13); | ||
| 195 | } | ||
| 216 | } | 196 | } |
| 217 | 197 | ||
| 218 | static u8 pdcnew_cable_detect(ide_hwif_t *hwif) | 198 | static u8 pdcnew_cable_detect(ide_hwif_t *hwif) |
| @@ -466,7 +446,7 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha | |||
| 466 | static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) | 446 | static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) |
| 467 | { | 447 | { |
| 468 | hwif->set_pio_mode = &pdcnew_set_pio_mode; | 448 | hwif->set_pio_mode = &pdcnew_set_pio_mode; |
| 469 | hwif->set_dma_mode = &pdcnew_set_mode; | 449 | hwif->set_dma_mode = &pdcnew_set_dma_mode; |
| 470 | 450 | ||
| 471 | hwif->quirkproc = &pdcnew_quirkproc; | 451 | hwif->quirkproc = &pdcnew_quirkproc; |
| 472 | hwif->resetproc = &pdcnew_reset; | 452 | hwif->resetproc = &pdcnew_reset; |
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index e09742e2ba59..67b2781e2213 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c | |||
| @@ -162,7 +162,7 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) | |||
| 162 | */ | 162 | */ |
| 163 | static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif) | 163 | static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif) |
| 164 | { | 164 | { |
| 165 | unsigned long clock_reg = hwif->dma_master + 0x11; | 165 | unsigned long clock_reg = hwif->extra_base + 0x01; |
| 166 | u8 clock = inb(clock_reg); | 166 | u8 clock = inb(clock_reg); |
| 167 | 167 | ||
| 168 | outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg); | 168 | outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg); |
| @@ -170,7 +170,7 @@ static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif) | |||
| 170 | 170 | ||
| 171 | static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) | 171 | static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) |
| 172 | { | 172 | { |
| 173 | unsigned long clock_reg = hwif->dma_master + 0x11; | 173 | unsigned long clock_reg = hwif->extra_base + 0x01; |
| 174 | u8 clock = inb(clock_reg); | 174 | u8 clock = inb(clock_reg); |
| 175 | 175 | ||
| 176 | outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); | 176 | outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); |
| @@ -193,7 +193,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) | |||
| 193 | if (drive->media != ide_disk || drive->addressing == 1) { | 193 | if (drive->media != ide_disk || drive->addressing == 1) { |
| 194 | struct request *rq = HWGROUP(drive)->rq; | 194 | struct request *rq = HWGROUP(drive)->rq; |
| 195 | ide_hwif_t *hwif = HWIF(drive); | 195 | ide_hwif_t *hwif = HWIF(drive); |
| 196 | unsigned long high_16 = hwif->dma_master; | 196 | unsigned long high_16 = hwif->extra_base - 16; |
| 197 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); | 197 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); |
| 198 | u32 word_count = 0; | 198 | u32 word_count = 0; |
| 199 | u8 clock = inb(high_16 + 0x11); | 199 | u8 clock = inb(high_16 + 0x11); |
| @@ -212,7 +212,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) | |||
| 212 | { | 212 | { |
| 213 | if (drive->media != ide_disk || drive->addressing == 1) { | 213 | if (drive->media != ide_disk || drive->addressing == 1) { |
| 214 | ide_hwif_t *hwif = HWIF(drive); | 214 | ide_hwif_t *hwif = HWIF(drive); |
| 215 | unsigned long high_16 = hwif->dma_master; | 215 | unsigned long high_16 = hwif->extra_base - 16; |
| 216 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); | 216 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); |
| 217 | u8 clock = 0; | 217 | u8 clock = 0; |
| 218 | 218 | ||
| @@ -228,7 +228,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) | |||
| 228 | static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive) | 228 | static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive) |
| 229 | { | 229 | { |
| 230 | ide_hwif_t *hwif = HWIF(drive); | 230 | ide_hwif_t *hwif = HWIF(drive); |
| 231 | unsigned long high_16 = hwif->dma_master; | 231 | unsigned long high_16 = hwif->extra_base - 16; |
| 232 | u8 dma_stat = inb(hwif->dma_status); | 232 | u8 dma_stat = inb(hwif->dma_status); |
| 233 | u8 sc1d = inb(high_16 + 0x001d); | 233 | u8 sc1d = inb(high_16 + 0x001d); |
| 234 | 234 | ||
| @@ -271,7 +271,7 @@ static void pdc202xx_dma_timeout(ide_drive_t *drive) | |||
| 271 | 271 | ||
| 272 | static void pdc202xx_reset_host (ide_hwif_t *hwif) | 272 | static void pdc202xx_reset_host (ide_hwif_t *hwif) |
| 273 | { | 273 | { |
| 274 | unsigned long high_16 = hwif->dma_master; | 274 | unsigned long high_16 = hwif->extra_base - 16; |
| 275 | u8 udma_speed_flag = inb(high_16 | 0x001f); | 275 | u8 udma_speed_flag = inb(high_16 | 0x001f); |
| 276 | 276 | ||
| 277 | outb(udma_speed_flag | 0x10, high_16 | 0x001f); | 277 | outb(udma_speed_flag | 0x10, high_16 | 0x001f); |
| @@ -375,6 +375,11 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev, | |||
| 375 | } | 375 | } |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | #define IDE_HFLAGS_PDC202XX \ | ||
| 379 | (IDE_HFLAG_ERROR_STOPS_FIFO | \ | ||
| 380 | IDE_HFLAG_ABUSE_SET_DMA_MODE | \ | ||
| 381 | IDE_HFLAG_OFF_BOARD) | ||
| 382 | |||
| 378 | #define DECLARE_PDC2026X_DEV(name_str, udma, extra_flags) \ | 383 | #define DECLARE_PDC2026X_DEV(name_str, udma, extra_flags) \ |
| 379 | { \ | 384 | { \ |
| 380 | .name = name_str, \ | 385 | .name = name_str, \ |
| @@ -382,9 +387,7 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev, | |||
| 382 | .init_hwif = init_hwif_pdc202xx, \ | 387 | .init_hwif = init_hwif_pdc202xx, \ |
| 383 | .init_dma = init_dma_pdc202xx, \ | 388 | .init_dma = init_dma_pdc202xx, \ |
| 384 | .extra = 48, \ | 389 | .extra = 48, \ |
| 385 | .host_flags = IDE_HFLAG_ERROR_STOPS_FIFO | \ | 390 | .host_flags = IDE_HFLAGS_PDC202XX | extra_flags, \ |
| 386 | extra_flags | \ | ||
| 387 | IDE_HFLAG_OFF_BOARD, \ | ||
| 388 | .pio_mask = ATA_PIO4, \ | 391 | .pio_mask = ATA_PIO4, \ |
| 389 | .mwdma_mask = ATA_MWDMA2, \ | 392 | .mwdma_mask = ATA_MWDMA2, \ |
| 390 | .udma_mask = udma, \ | 393 | .udma_mask = udma, \ |
| @@ -397,8 +400,7 @@ static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = { | |||
| 397 | .init_hwif = init_hwif_pdc202xx, | 400 | .init_hwif = init_hwif_pdc202xx, |
| 398 | .init_dma = init_dma_pdc202xx, | 401 | .init_dma = init_dma_pdc202xx, |
| 399 | .extra = 16, | 402 | .extra = 16, |
| 400 | .host_flags = IDE_HFLAG_ERROR_STOPS_FIFO | | 403 | .host_flags = IDE_HFLAGS_PDC202XX, |
| 401 | IDE_HFLAG_OFF_BOARD, | ||
| 402 | .pio_mask = ATA_PIO4, | 404 | .pio_mask = ATA_PIO4, |
| 403 | .mwdma_mask = ATA_MWDMA2, | 405 | .mwdma_mask = ATA_MWDMA2, |
| 404 | .udma_mask = ATA_UDMA2, | 406 | .udma_mask = ATA_UDMA2, |
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 27781d294cea..bd6d3f77d30c 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c | |||
| @@ -203,20 +203,11 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 203 | pci_read_config_byte(dev, 0x54, ®54); | 203 | pci_read_config_byte(dev, 0x54, ®54); |
| 204 | pci_read_config_byte(dev, 0x55, ®55); | 204 | pci_read_config_byte(dev, 0x55, ®55); |
| 205 | 205 | ||
| 206 | switch(speed) { | ||
| 207 | case XFER_UDMA_4: | ||
| 208 | case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; | ||
| 209 | case XFER_UDMA_5: | ||
| 210 | case XFER_UDMA_3: | ||
| 211 | case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; | ||
| 212 | case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; | ||
| 213 | case XFER_MW_DMA_2: | ||
| 214 | case XFER_MW_DMA_1: | ||
| 215 | case XFER_SW_DMA_2: break; | ||
| 216 | default: return; | ||
| 217 | } | ||
| 218 | |||
| 219 | if (speed >= XFER_UDMA_0) { | 206 | if (speed >= XFER_UDMA_0) { |
| 207 | u8 udma = speed - XFER_UDMA_0; | ||
| 208 | |||
| 209 | u_speed = min_t(u8, 2 - (udma & 1), udma) << (drive->dn * 4); | ||
| 210 | |||
| 220 | if (!(reg48 & u_flag)) | 211 | if (!(reg48 & u_flag)) |
| 221 | pci_write_config_byte(dev, 0x48, reg48 | u_flag); | 212 | pci_write_config_byte(dev, 0x48, reg48 | u_flag); |
| 222 | if (speed == XFER_UDMA_5) { | 213 | if (speed == XFER_UDMA_5) { |
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 707d5ff66b03..fef20bd4aa78 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c | |||
| @@ -135,59 +135,29 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
| 135 | unsigned short pci_clock; | 135 | unsigned short pci_clock; |
| 136 | unsigned int basereg = hwif->channel ? 0x50 : 0x40; | 136 | unsigned int basereg = hwif->channel ? 0x50 : 0x40; |
| 137 | 137 | ||
| 138 | static const u32 udma_timing[3][3] = { | ||
| 139 | { 0x00921250, 0x00911140, 0x00911030 }, | ||
| 140 | { 0x00932470, 0x00922260, 0x00922140 }, | ||
| 141 | { 0x009436a1, 0x00933481, 0x00923261 }, | ||
| 142 | }; | ||
| 143 | |||
| 144 | static const u32 mwdma_timing[3][3] = { | ||
| 145 | { 0x00077771, 0x00012121, 0x00002020 }, | ||
| 146 | { 0x000bbbb2, 0x00024241, 0x00013131 }, | ||
| 147 | { 0x000ffff3, 0x00035352, 0x00015151 }, | ||
| 148 | }; | ||
| 149 | |||
| 138 | pci_clock = sc1200_get_pci_clock(); | 150 | pci_clock = sc1200_get_pci_clock(); |
| 139 | 151 | ||
| 140 | /* | 152 | /* |
| 141 | * Note that each DMA mode has several timings associated with it. | 153 | * Note that each DMA mode has several timings associated with it. |
| 142 | * The correct timing depends on the fast PCI clock freq. | 154 | * The correct timing depends on the fast PCI clock freq. |
| 143 | */ | 155 | */ |
| 144 | timings = 0; | 156 | |
| 145 | switch (mode) { | 157 | if (mode >= XFER_UDMA_0) |
| 146 | case XFER_UDMA_0: | 158 | timings = udma_timing[pci_clock][mode - XFER_UDMA_0]; |
| 147 | switch (pci_clock) { | 159 | else |
| 148 | case PCI_CLK_33: timings = 0x00921250; break; | 160 | timings = mwdma_timing[pci_clock][mode - XFER_MW_DMA_0]; |
| 149 | case PCI_CLK_48: timings = 0x00932470; break; | ||
| 150 | case PCI_CLK_66: timings = 0x009436a1; break; | ||
| 151 | } | ||
| 152 | break; | ||
| 153 | case XFER_UDMA_1: | ||
| 154 | switch (pci_clock) { | ||
| 155 | case PCI_CLK_33: timings = 0x00911140; break; | ||
| 156 | case PCI_CLK_48: timings = 0x00922260; break; | ||
| 157 | case PCI_CLK_66: timings = 0x00933481; break; | ||
| 158 | } | ||
| 159 | break; | ||
| 160 | case XFER_UDMA_2: | ||
| 161 | switch (pci_clock) { | ||
| 162 | case PCI_CLK_33: timings = 0x00911030; break; | ||
| 163 | case PCI_CLK_48: timings = 0x00922140; break; | ||
| 164 | case PCI_CLK_66: timings = 0x00923261; break; | ||
| 165 | } | ||
| 166 | break; | ||
| 167 | case XFER_MW_DMA_0: | ||
| 168 | switch (pci_clock) { | ||
| 169 | case PCI_CLK_33: timings = 0x00077771; break; | ||
| 170 | case PCI_CLK_48: timings = 0x000bbbb2; break; | ||
| 171 | case PCI_CLK_66: timings = 0x000ffff3; break; | ||
| 172 | } | ||
| 173 | break; | ||
| 174 | case XFER_MW_DMA_1: | ||
| 175 | switch (pci_clock) { | ||
| 176 | case PCI_CLK_33: timings = 0x00012121; break; | ||
| 177 | case PCI_CLK_48: timings = 0x00024241; break; | ||
| 178 | case PCI_CLK_66: timings = 0x00035352; break; | ||
| 179 | } | ||
| 180 | break; | ||
| 181 | case XFER_MW_DMA_2: | ||
| 182 | switch (pci_clock) { | ||
| 183 | case PCI_CLK_33: timings = 0x00002020; break; | ||
| 184 | case PCI_CLK_48: timings = 0x00013131; break; | ||
| 185 | case PCI_CLK_66: timings = 0x00015151; break; | ||
| 186 | } | ||
| 187 | break; | ||
| 188 | default: | ||
| 189 | return; | ||
| 190 | } | ||
| 191 | 161 | ||
| 192 | if (unit == 0) { /* are we configuring drive0? */ | 162 | if (unit == 0) { /* are we configuring drive0? */ |
| 193 | pci_read_config_dword(hwif->pci_dev, basereg+4, ®); | 163 | pci_read_config_dword(hwif->pci_dev, basereg+4, ®); |
| @@ -260,66 +230,39 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 260 | } | 230 | } |
| 261 | 231 | ||
| 262 | #ifdef CONFIG_PM | 232 | #ifdef CONFIG_PM |
| 263 | static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev) | 233 | struct sc1200_saved_state { |
| 264 | { | 234 | u32 regs[8]; |
| 265 | int h; | 235 | }; |
| 266 | |||
| 267 | for (h = 0; h < MAX_HWIFS; h++) { | ||
| 268 | ide_hwif_t *hwif = &ide_hwifs[h]; | ||
| 269 | if (prev) { | ||
| 270 | if (hwif == prev) | ||
| 271 | prev = NULL; // found previous, now look for next match | ||
| 272 | } else { | ||
| 273 | if (hwif && hwif->pci_dev == dev) | ||
| 274 | return hwif; // found next match | ||
| 275 | } | ||
| 276 | } | ||
| 277 | return NULL; // not found | ||
| 278 | } | ||
| 279 | |||
| 280 | typedef struct sc1200_saved_state_s { | ||
| 281 | __u32 regs[4]; | ||
| 282 | } sc1200_saved_state_t; | ||
| 283 | |||
| 284 | 236 | ||
| 285 | static int sc1200_suspend (struct pci_dev *dev, pm_message_t state) | 237 | static int sc1200_suspend (struct pci_dev *dev, pm_message_t state) |
| 286 | { | 238 | { |
| 287 | ide_hwif_t *hwif = NULL; | ||
| 288 | |||
| 289 | printk("SC1200: suspend(%u)\n", state.event); | 239 | printk("SC1200: suspend(%u)\n", state.event); |
| 290 | 240 | ||
| 241 | /* | ||
| 242 | * we only save state when going from full power to less | ||
| 243 | */ | ||
| 291 | if (state.event == PM_EVENT_ON) { | 244 | if (state.event == PM_EVENT_ON) { |
| 292 | // we only save state when going from full power to less | 245 | struct sc1200_saved_state *ss; |
| 293 | 246 | unsigned int r; | |
| 294 | // | 247 | |
| 295 | // Loop over all interfaces that are part of this PCI device: | 248 | /* |
| 296 | // | 249 | * allocate a permanent save area, if not already allocated |
| 297 | while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { | 250 | */ |
| 298 | sc1200_saved_state_t *ss; | 251 | ss = (struct sc1200_saved_state *)pci_get_drvdata(dev); |
| 299 | unsigned int basereg, r; | 252 | if (ss == NULL) { |
| 300 | // | 253 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); |
| 301 | // allocate a permanent save area, if not already allocated | 254 | if (ss == NULL) |
| 302 | // | 255 | return -ENOMEM; |
| 303 | ss = (sc1200_saved_state_t *)hwif->config_data; | 256 | pci_set_drvdata(dev, ss); |
| 304 | if (ss == NULL) { | ||
| 305 | ss = kmalloc(sizeof(sc1200_saved_state_t), GFP_KERNEL); | ||
| 306 | if (ss == NULL) | ||
| 307 | return -ENOMEM; | ||
| 308 | hwif->config_data = (unsigned long)ss; | ||
| 309 | } | ||
| 310 | ss = (sc1200_saved_state_t *)hwif->config_data; | ||
| 311 | // | ||
| 312 | // Save timing registers: this may be unnecessary if | ||
| 313 | // BIOS also does it | ||
| 314 | // | ||
| 315 | basereg = hwif->channel ? 0x50 : 0x40; | ||
| 316 | for (r = 0; r < 4; ++r) { | ||
| 317 | pci_read_config_dword (hwif->pci_dev, basereg + (r<<2), &ss->regs[r]); | ||
| 318 | } | ||
| 319 | } | 257 | } |
| 320 | } | ||
| 321 | 258 | ||
| 322 | /* You don't need to iterate over disks -- sysfs should have done that for you already */ | 259 | /* |
| 260 | * save timing registers | ||
| 261 | * (this may be unnecessary if BIOS also does it) | ||
| 262 | */ | ||
| 263 | for (r = 0; r < 8; r++) | ||
| 264 | pci_read_config_dword(dev, 0x40 + r * 4, &ss->regs[r]); | ||
| 265 | } | ||
| 323 | 266 | ||
| 324 | pci_disable_device(dev); | 267 | pci_disable_device(dev); |
| 325 | pci_set_power_state(dev, pci_choose_state(dev, state)); | 268 | pci_set_power_state(dev, pci_choose_state(dev, state)); |
| @@ -328,30 +271,25 @@ static int sc1200_suspend (struct pci_dev *dev, pm_message_t state) | |||
| 328 | 271 | ||
| 329 | static int sc1200_resume (struct pci_dev *dev) | 272 | static int sc1200_resume (struct pci_dev *dev) |
| 330 | { | 273 | { |
| 331 | ide_hwif_t *hwif = NULL; | 274 | struct sc1200_saved_state *ss; |
| 332 | int i; | 275 | unsigned int r; |
| 276 | int i; | ||
| 333 | 277 | ||
| 334 | i = pci_enable_device(dev); | 278 | i = pci_enable_device(dev); |
| 335 | if (i) | 279 | if (i) |
| 336 | return i; | 280 | return i; |
| 337 | 281 | ||
| 338 | // | 282 | ss = (struct sc1200_saved_state *)pci_get_drvdata(dev); |
| 339 | // loop over all interfaces that are part of this pci device: | 283 | |
| 340 | // | 284 | /* |
| 341 | while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { | 285 | * restore timing registers |
| 342 | unsigned int basereg, r; | 286 | * (this may be unnecessary if BIOS also does it) |
| 343 | sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data; | 287 | */ |
| 344 | 288 | if (ss) { | |
| 345 | // | 289 | for (r = 0; r < 8; r++) |
| 346 | // Restore timing registers: this may be unnecessary if BIOS also does it | 290 | pci_write_config_dword(dev, 0x40 + r * 4, ss->regs[r]); |
| 347 | // | ||
| 348 | basereg = hwif->channel ? 0x50 : 0x40; | ||
| 349 | if (ss != NULL) { | ||
| 350 | for (r = 0; r < 4; ++r) { | ||
| 351 | pci_write_config_dword(hwif->pci_dev, basereg + (r<<2), ss->regs[r]); | ||
| 352 | } | ||
| 353 | } | ||
| 354 | } | 291 | } |
| 292 | |||
| 355 | return 0; | 293 | return 0; |
| 356 | } | 294 | } |
| 357 | #endif | 295 | #endif |
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index ebb7132b9b84..24a85bbcd2a6 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c | |||
| @@ -254,19 +254,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 254 | offset = 0; /* 100MHz */ | 254 | offset = 0; /* 100MHz */ |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | switch (speed) { | 257 | idx = speed - XFER_UDMA_0; |
| 258 | case XFER_UDMA_6: | ||
| 259 | case XFER_UDMA_5: | ||
| 260 | case XFER_UDMA_4: | ||
| 261 | case XFER_UDMA_3: | ||
| 262 | case XFER_UDMA_2: | ||
| 263 | case XFER_UDMA_1: | ||
| 264 | case XFER_UDMA_0: | ||
| 265 | idx = speed - XFER_UDMA_0; | ||
| 266 | break; | ||
| 267 | default: | ||
| 268 | return; | ||
| 269 | } | ||
| 270 | 258 | ||
| 271 | jcactsel = JCACTSELtbl[offset][idx]; | 259 | jcactsel = JCACTSELtbl[offset][idx]; |
| 272 | if (is_slave) { | 260 | if (is_slave) { |
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index a7280311357b..e9bd269547bb 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c | |||
| @@ -366,12 +366,17 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) | |||
| 366 | } | 366 | } |
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | #define IDE_HFLAGS_SVWKS \ | ||
| 370 | (IDE_HFLAG_LEGACY_IRQS | \ | ||
| 371 | IDE_HFLAG_ABUSE_SET_DMA_MODE | \ | ||
| 372 | IDE_HFLAG_BOOTABLE) | ||
| 373 | |||
| 369 | static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | 374 | static const struct ide_port_info serverworks_chipsets[] __devinitdata = { |
| 370 | { /* 0 */ | 375 | { /* 0 */ |
| 371 | .name = "SvrWks OSB4", | 376 | .name = "SvrWks OSB4", |
| 372 | .init_chipset = init_chipset_svwks, | 377 | .init_chipset = init_chipset_svwks, |
| 373 | .init_hwif = init_hwif_svwks, | 378 | .init_hwif = init_hwif_svwks, |
| 374 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, | 379 | .host_flags = IDE_HFLAGS_SVWKS, |
| 375 | .pio_mask = ATA_PIO4, | 380 | .pio_mask = ATA_PIO4, |
| 376 | .mwdma_mask = ATA_MWDMA2, | 381 | .mwdma_mask = ATA_MWDMA2, |
| 377 | .udma_mask = 0x00, /* UDMA is problematic on OSB4 */ | 382 | .udma_mask = 0x00, /* UDMA is problematic on OSB4 */ |
| @@ -379,7 +384,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | |||
| 379 | .name = "SvrWks CSB5", | 384 | .name = "SvrWks CSB5", |
| 380 | .init_chipset = init_chipset_svwks, | 385 | .init_chipset = init_chipset_svwks, |
| 381 | .init_hwif = init_hwif_svwks, | 386 | .init_hwif = init_hwif_svwks, |
| 382 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, | 387 | .host_flags = IDE_HFLAGS_SVWKS, |
| 383 | .pio_mask = ATA_PIO4, | 388 | .pio_mask = ATA_PIO4, |
| 384 | .mwdma_mask = ATA_MWDMA2, | 389 | .mwdma_mask = ATA_MWDMA2, |
| 385 | .udma_mask = ATA_UDMA5, | 390 | .udma_mask = ATA_UDMA5, |
| @@ -387,7 +392,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | |||
| 387 | .name = "SvrWks CSB6", | 392 | .name = "SvrWks CSB6", |
| 388 | .init_chipset = init_chipset_svwks, | 393 | .init_chipset = init_chipset_svwks, |
| 389 | .init_hwif = init_hwif_svwks, | 394 | .init_hwif = init_hwif_svwks, |
| 390 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, | 395 | .host_flags = IDE_HFLAGS_SVWKS, |
| 391 | .pio_mask = ATA_PIO4, | 396 | .pio_mask = ATA_PIO4, |
| 392 | .mwdma_mask = ATA_MWDMA2, | 397 | .mwdma_mask = ATA_MWDMA2, |
| 393 | .udma_mask = ATA_UDMA5, | 398 | .udma_mask = ATA_UDMA5, |
| @@ -395,8 +400,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | |||
| 395 | .name = "SvrWks CSB6", | 400 | .name = "SvrWks CSB6", |
| 396 | .init_chipset = init_chipset_svwks, | 401 | .init_chipset = init_chipset_svwks, |
| 397 | .init_hwif = init_hwif_svwks, | 402 | .init_hwif = init_hwif_svwks, |
| 398 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE | | 403 | .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE, |
| 399 | IDE_HFLAG_BOOTABLE, | ||
| 400 | .pio_mask = ATA_PIO4, | 404 | .pio_mask = ATA_PIO4, |
| 401 | .mwdma_mask = ATA_MWDMA2, | 405 | .mwdma_mask = ATA_MWDMA2, |
| 402 | .udma_mask = ATA_UDMA5, | 406 | .udma_mask = ATA_UDMA5, |
| @@ -404,8 +408,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | |||
| 404 | .name = "SvrWks HT1000", | 408 | .name = "SvrWks HT1000", |
| 405 | .init_chipset = init_chipset_svwks, | 409 | .init_chipset = init_chipset_svwks, |
| 406 | .init_hwif = init_hwif_svwks, | 410 | .init_hwif = init_hwif_svwks, |
| 407 | .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE | | 411 | .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE, |
| 408 | IDE_HFLAG_BOOTABLE, | ||
| 409 | .pio_mask = ATA_PIO4, | 412 | .pio_mask = ATA_PIO4, |
| 410 | .mwdma_mask = ATA_MWDMA2, | 413 | .mwdma_mask = ATA_MWDMA2, |
| 411 | .udma_mask = ATA_UDMA5, | 414 | .udma_mask = ATA_UDMA5, |
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index de820aa58cd0..7e9dade5648d 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
| @@ -582,7 +582,6 @@ ide_init_sgiioc4(ide_hwif_t * hwif) | |||
| 582 | hwif->pre_reset = NULL; /* No HBA specific pre_set needed */ | 582 | hwif->pre_reset = NULL; /* No HBA specific pre_set needed */ |
| 583 | hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine, | 583 | hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine, |
| 584 | clear interrupts */ | 584 | clear interrupts */ |
| 585 | hwif->intrproc = NULL; /* Enable or Disable interrupt from drive */ | ||
| 586 | hwif->maskproc = &sgiioc4_maskproc; /* Mask on/off NIEN register */ | 585 | hwif->maskproc = &sgiioc4_maskproc; /* Mask on/off NIEN register */ |
| 587 | hwif->quirkproc = NULL; | 586 | hwif->quirkproc = NULL; |
| 588 | hwif->busproc = NULL; | 587 | hwif->busproc = NULL; |
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 5709c252543b..7b45eaf5afd9 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
| @@ -278,27 +278,14 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 278 | 278 | ||
| 279 | scsc = is_sata(hwif) ? 1 : scsc; | 279 | scsc = is_sata(hwif) ? 1 : scsc; |
| 280 | 280 | ||
| 281 | switch(speed) { | 281 | if (speed >= XFER_UDMA_0) { |
| 282 | case XFER_MW_DMA_2: | 282 | multi = dma[2]; |
| 283 | case XFER_MW_DMA_1: | 283 | ultra |= (scsc ? ultra6[speed - XFER_UDMA_0] : |
| 284 | case XFER_MW_DMA_0: | 284 | ultra5[speed - XFER_UDMA_0]); |
| 285 | multi = dma[speed - XFER_MW_DMA_0]; | 285 | mode |= (unit ? 0x30 : 0x03); |
| 286 | mode |= ((unit) ? 0x20 : 0x02); | 286 | } else { |
| 287 | break; | 287 | multi = dma[speed - XFER_MW_DMA_0]; |
| 288 | case XFER_UDMA_6: | 288 | mode |= (unit ? 0x20 : 0x02); |
| 289 | case XFER_UDMA_5: | ||
| 290 | case XFER_UDMA_4: | ||
| 291 | case XFER_UDMA_3: | ||
| 292 | case XFER_UDMA_2: | ||
| 293 | case XFER_UDMA_1: | ||
| 294 | case XFER_UDMA_0: | ||
| 295 | multi = dma[2]; | ||
| 296 | ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) : | ||
| 297 | (ultra5[speed - XFER_UDMA_0])); | ||
| 298 | mode |= ((unit) ? 0x30 : 0x03); | ||
| 299 | break; | ||
| 300 | default: | ||
| 301 | return; | ||
| 302 | } | 289 | } |
| 303 | 290 | ||
| 304 | if (hwif->mmio) { | 291 | if (hwif->mmio) { |
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index d90b42917775..85d36996e6af 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c | |||
| @@ -305,59 +305,56 @@ static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 305 | sis_program_timings(drive, XFER_PIO_0 + pio); | 305 | sis_program_timings(drive, XFER_PIO_0 + pio); |
| 306 | } | 306 | } |
| 307 | 307 | ||
| 308 | static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed) | 308 | static void sis_ata133_program_udma_timings(ide_drive_t *drive, const u8 mode) |
| 309 | { | 309 | { |
| 310 | ide_hwif_t *hwif = HWIF(drive); | 310 | struct pci_dev *dev = drive->hwif->pci_dev; |
| 311 | struct pci_dev *dev = hwif->pci_dev; | 311 | u32 regdw = 0; |
| 312 | u8 drive_pci = sis_ata133_get_base(drive), clk, idx; | ||
| 312 | 313 | ||
| 313 | /* Config chip for mode */ | 314 | pci_read_config_dword(dev, drive_pci, ®dw); |
| 314 | switch(speed) { | 315 | |
| 315 | case XFER_UDMA_6: | 316 | regdw |= 0x04; |
| 316 | case XFER_UDMA_5: | 317 | regdw &= 0xfffff00f; |
| 317 | case XFER_UDMA_4: | 318 | /* check if ATA133 enable */ |
| 318 | case XFER_UDMA_3: | 319 | clk = (regdw & 0x08) ? ATA_133 : ATA_100; |
| 319 | case XFER_UDMA_2: | 320 | idx = mode - XFER_UDMA_0; |
| 320 | case XFER_UDMA_1: | 321 | regdw |= cycle_time_value[clk][idx] << 4; |
| 321 | case XFER_UDMA_0: | 322 | regdw |= cvs_time_value[clk][idx] << 8; |
| 322 | if (chipset_family >= ATA_133) { | 323 | |
| 323 | u32 regdw = 0; | 324 | pci_write_config_dword(dev, drive_pci, regdw); |
| 324 | u8 drive_pci = sis_ata133_get_base(drive); | 325 | } |
| 325 | 326 | ||
| 326 | pci_read_config_dword(dev, drive_pci, ®dw); | 327 | static void sis_ata33_program_udma_timings(ide_drive_t *drive, const u8 mode) |
| 327 | regdw |= 0x04; | 328 | { |
| 328 | regdw &= 0xfffff00f; | 329 | struct pci_dev *dev = drive->hwif->pci_dev; |
| 329 | /* check if ATA133 enable */ | 330 | u8 drive_pci = 0x40 + drive->dn * 2, reg = 0, i = chipset_family; |
| 330 | if (regdw & 0x08) { | 331 | |
| 331 | regdw |= (unsigned long)cycle_time_value[ATA_133][speed-XFER_UDMA_0] << 4; | 332 | pci_read_config_byte(dev, drive_pci + 1, ®); |
| 332 | regdw |= (unsigned long)cvs_time_value[ATA_133][speed-XFER_UDMA_0] << 8; | 333 | |
| 333 | } else { | 334 | /* force the UDMA bit on if we want to use UDMA */ |
| 334 | regdw |= (unsigned long)cycle_time_value[ATA_100][speed-XFER_UDMA_0] << 4; | 335 | reg |= 0x80; |
| 335 | regdw |= (unsigned long)cvs_time_value[ATA_100][speed-XFER_UDMA_0] << 8; | 336 | /* clean reg cycle time bits */ |
| 336 | } | 337 | reg &= ~((0xff >> (8 - cycle_time_range[i])) << cycle_time_offset[i]); |
| 337 | pci_write_config_dword(dev, (unsigned long)drive_pci, regdw); | 338 | /* set reg cycle time bits */ |
| 338 | } else { | 339 | reg |= cycle_time_value[i][mode - XFER_UDMA_0] << cycle_time_offset[i]; |
| 339 | u8 drive_pci = 0x40 + drive->dn * 2, reg = 0; | 340 | |
| 340 | 341 | pci_write_config_byte(dev, drive_pci + 1, reg); | |
| 341 | pci_read_config_byte(dev, drive_pci+1, ®); | 342 | } |
| 342 | /* Force the UDMA bit on if we want to use UDMA */ | 343 | |
| 343 | reg |= 0x80; | 344 | static void sis_program_udma_timings(ide_drive_t *drive, const u8 mode) |
| 344 | /* clean reg cycle time bits */ | 345 | { |
| 345 | reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family])) | 346 | if (chipset_family >= ATA_133) /* ATA_133 */ |
| 346 | << cycle_time_offset[chipset_family]); | 347 | sis_ata133_program_udma_timings(drive, mode); |
| 347 | /* set reg cycle time bits */ | 348 | else /* ATA_33/66/100a/100/133a */ |
| 348 | reg |= cycle_time_value[chipset_family][speed-XFER_UDMA_0] | 349 | sis_ata33_program_udma_timings(drive, mode); |
| 349 | << cycle_time_offset[chipset_family]; | 350 | } |
| 350 | pci_write_config_byte(dev, drive_pci+1, reg); | 351 | |
| 351 | } | 352 | static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed) |
| 352 | break; | 353 | { |
| 353 | case XFER_MW_DMA_2: | 354 | if (speed >= XFER_UDMA_0) |
| 354 | case XFER_MW_DMA_1: | 355 | sis_program_udma_timings(drive, speed); |
| 355 | case XFER_MW_DMA_0: | 356 | else |
| 356 | sis_program_timings(drive, speed); | 357 | sis_program_timings(drive, speed); |
| 357 | break; | ||
| 358 | default: | ||
| 359 | break; | ||
| 360 | } | ||
| 361 | } | 358 | } |
| 362 | 359 | ||
| 363 | static u8 sis5513_ata133_udma_filter(ide_drive_t *drive) | 360 | static u8 sis5513_ata133_udma_filter(ide_drive_t *drive) |
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 147d783f7529..069f104fdcea 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c | |||
| @@ -115,32 +115,24 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 115 | DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n", | 115 | DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n", |
| 116 | drive->name, ide_xfer_verbose(speed))); | 116 | drive->name, ide_xfer_verbose(speed))); |
| 117 | 117 | ||
| 118 | switch (speed) { | 118 | drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0]; |
| 119 | case XFER_MW_DMA_2: | ||
| 120 | case XFER_MW_DMA_1: | ||
| 121 | case XFER_MW_DMA_0: | ||
| 122 | drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0]; | ||
| 123 | 119 | ||
| 124 | /* | 120 | /* |
| 125 | * Store the DMA timings so that we can actually program | 121 | * Store the DMA timings so that we can actually program |
| 126 | * them when DMA will be turned on... | 122 | * them when DMA will be turned on... |
| 127 | */ | 123 | */ |
| 128 | drive->drive_data &= 0x0000ffff; | 124 | drive->drive_data &= 0x0000ffff; |
| 129 | drive->drive_data |= (unsigned long)drv_ctrl << 16; | 125 | drive->drive_data |= (unsigned long)drv_ctrl << 16; |
| 130 | 126 | ||
| 131 | /* | 127 | /* |
| 132 | * If we are already using DMA, we just reprogram | 128 | * If we are already using DMA, we just reprogram |
| 133 | * the drive control register. | 129 | * the drive control register. |
| 134 | */ | 130 | */ |
| 135 | if (drive->using_dma) { | 131 | if (drive->using_dma) { |
| 136 | struct pci_dev *dev = HWIF(drive)->pci_dev; | 132 | struct pci_dev *dev = HWIF(drive)->pci_dev; |
| 137 | int reg = 0x44 + drive->dn * 4; | 133 | int reg = 0x44 + drive->dn * 4; |
| 138 | 134 | ||
| 139 | pci_write_config_word(dev, reg, drv_ctrl); | 135 | pci_write_config_word(dev, reg, drv_ctrl); |
| 140 | } | ||
| 141 | break; | ||
| 142 | default: | ||
| 143 | return; | ||
| 144 | } | 136 | } |
| 145 | } | 137 | } |
| 146 | 138 | ||
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index eb4445b229ed..dbbb46819a2d 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c | |||
| @@ -91,19 +91,9 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 91 | pci_read_config_word(dev, 0x48, ®48); | 91 | pci_read_config_word(dev, 0x48, ®48); |
| 92 | pci_read_config_word(dev, 0x4a, ®4a); | 92 | pci_read_config_word(dev, 0x4a, ®4a); |
| 93 | 93 | ||
| 94 | switch(speed) { | ||
| 95 | case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; | ||
| 96 | case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; | ||
| 97 | case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; | ||
| 98 | case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; | ||
| 99 | case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; | ||
| 100 | case XFER_MW_DMA_2: | ||
| 101 | case XFER_MW_DMA_1: | ||
| 102 | case XFER_SW_DMA_2: break; | ||
| 103 | default: return; | ||
| 104 | } | ||
| 105 | |||
| 106 | if (speed >= XFER_UDMA_0) { | 94 | if (speed >= XFER_UDMA_0) { |
| 95 | u_speed = (speed - XFER_UDMA_0) << (drive->dn * 4); | ||
| 96 | |||
| 107 | if (!(reg48 & u_flag)) | 97 | if (!(reg48 & u_flag)) |
| 108 | pci_write_config_word(dev, 0x48, reg48|u_flag); | 98 | pci_write_config_word(dev, 0x48, reg48|u_flag); |
| 109 | /* FIXME: (reg4a & a_speed) ? */ | 99 | /* FIXME: (reg4a & a_speed) ? */ |
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c index a66ebd14664e..e1faf6c2fe16 100644 --- a/drivers/ide/pci/tc86c001.c +++ b/drivers/ide/pci/tc86c001.c | |||
| @@ -222,7 +222,8 @@ static const struct ide_port_info tc86c001_chipset __devinitdata = { | |||
| 222 | .name = "TC86C001", | 222 | .name = "TC86C001", |
| 223 | .init_chipset = init_chipset_tc86c001, | 223 | .init_chipset = init_chipset_tc86c001, |
| 224 | .init_hwif = init_hwif_tc86c001, | 224 | .init_hwif = init_hwif_tc86c001, |
| 225 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD, | 225 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD | |
| 226 | IDE_HFLAG_ABUSE_SET_DMA_MODE, | ||
| 226 | .pio_mask = ATA_PIO4, | 227 | .pio_mask = ATA_PIO4, |
| 227 | .mwdma_mask = ATA_MWDMA2, | 228 | .mwdma_mask = ATA_MWDMA2, |
| 228 | .udma_mask = ATA_UDMA4, | 229 | .udma_mask = ATA_UDMA4, |
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index a227c41d23a3..ae52a96a1cf9 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c | |||
| @@ -81,8 +81,6 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed) | |||
| 81 | case XFER_PIO_0: | 81 | case XFER_PIO_0: |
| 82 | timing = 0x0808; | 82 | timing = 0x0808; |
| 83 | break; | 83 | break; |
| 84 | default: | ||
| 85 | return; | ||
| 86 | } | 84 | } |
| 87 | 85 | ||
| 88 | triflex_timings &= ~(0xFFFF << (16 * unit)); | 86 | triflex_timings &= ~(0xFFFF << (16 * unit)); |
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index a0d3c16b68ec..4b32c90f4896 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c | |||
| @@ -439,6 +439,7 @@ static const struct ide_port_info via82cxxx_chipset __devinitdata = { | |||
| 439 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, | 439 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, |
| 440 | .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | | 440 | .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | |
| 441 | IDE_HFLAG_PIO_NO_DOWNGRADE | | 441 | IDE_HFLAG_PIO_NO_DOWNGRADE | |
| 442 | IDE_HFLAG_ABUSE_SET_DMA_MODE | | ||
| 442 | IDE_HFLAG_POST_SET_MODE | | 443 | IDE_HFLAG_POST_SET_MODE | |
| 443 | IDE_HFLAG_IO_32BIT | | 444 | IDE_HFLAG_IO_32BIT | |
| 444 | IDE_HFLAG_BOOTABLE, | 445 | IDE_HFLAG_BOOTABLE, |
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 7f7a59885777..3dce80092fff 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
| @@ -438,13 +438,8 @@ pmac_ide_init_hwif_ports(hw_regs_t *hw, | |||
| 438 | if (data_port == pmac_ide[ix].regbase) | 438 | if (data_port == pmac_ide[ix].regbase) |
| 439 | break; | 439 | break; |
| 440 | 440 | ||
| 441 | if (ix >= MAX_HWIFS) { | 441 | if (ix >= MAX_HWIFS) |
| 442 | /* Probably a PCI interface... */ | 442 | return; /* not an IDE PMAC interface */ |
| 443 | for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; ++i) | ||
| 444 | hw->io_ports[i] = data_port + i - IDE_DATA_OFFSET; | ||
| 445 | hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; | ||
| 446 | return; | ||
| 447 | } | ||
| 448 | 443 | ||
| 449 | for (i = 0; i < 8; ++i) | 444 | for (i = 0; i < 8; ++i) |
| 450 | hw->io_ports[i] = data_port + i * 0x10; | 445 | hw->io_ports[i] = data_port + i * 0x10; |
| @@ -833,38 +828,20 @@ static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 833 | tl[0] = *timings; | 828 | tl[0] = *timings; |
| 834 | tl[1] = *timings2; | 829 | tl[1] = *timings2; |
| 835 | 830 | ||
| 836 | switch(speed) { | ||
| 837 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC | 831 | #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC |
| 838 | case XFER_UDMA_6: | 832 | if (speed >= XFER_UDMA_0) { |
| 839 | case XFER_UDMA_5: | 833 | if (pmif->kind == controller_kl_ata4) |
| 840 | case XFER_UDMA_4: | 834 | ret = set_timings_udma_ata4(&tl[0], speed); |
| 841 | case XFER_UDMA_3: | 835 | else if (pmif->kind == controller_un_ata6 |
| 842 | case XFER_UDMA_2: | 836 | || pmif->kind == controller_k2_ata6) |
| 843 | case XFER_UDMA_1: | 837 | ret = set_timings_udma_ata6(&tl[0], &tl[1], speed); |
| 844 | case XFER_UDMA_0: | 838 | else if (pmif->kind == controller_sh_ata6) |
| 845 | if (pmif->kind == controller_kl_ata4) | 839 | ret = set_timings_udma_shasta(&tl[0], &tl[1], speed); |
| 846 | ret = set_timings_udma_ata4(&tl[0], speed); | 840 | else |
| 847 | else if (pmif->kind == controller_un_ata6 | 841 | ret = -1; |
| 848 | || pmif->kind == controller_k2_ata6) | 842 | } else |
| 849 | ret = set_timings_udma_ata6(&tl[0], &tl[1], speed); | 843 | set_timings_mdma(drive, pmif->kind, &tl[0], &tl[1], speed); |
| 850 | else if (pmif->kind == controller_sh_ata6) | ||
| 851 | ret = set_timings_udma_shasta(&tl[0], &tl[1], speed); | ||
| 852 | else | ||
| 853 | ret = 1; | ||
| 854 | break; | ||
| 855 | case XFER_MW_DMA_2: | ||
| 856 | case XFER_MW_DMA_1: | ||
| 857 | case XFER_MW_DMA_0: | ||
| 858 | set_timings_mdma(drive, pmif->kind, &tl[0], &tl[1], speed); | ||
| 859 | break; | ||
| 860 | case XFER_SW_DMA_2: | ||
| 861 | case XFER_SW_DMA_1: | ||
| 862 | case XFER_SW_DMA_0: | ||
| 863 | return; | ||
| 864 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ | 844 | #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ |
| 865 | default: | ||
| 866 | ret = 1; | ||
| 867 | } | ||
| 868 | if (ret) | 845 | if (ret) |
| 869 | return; | 846 | return; |
| 870 | 847 | ||
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 9706de9d98d5..02e91893064d 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
| @@ -395,14 +395,12 @@ static int idescsi_expiry(ide_drive_t *drive) | |||
| 395 | static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) | 395 | static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) |
| 396 | { | 396 | { |
| 397 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | 397 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
| 398 | idescsi_pc_t *pc=scsi->pc; | 398 | ide_hwif_t *hwif = drive->hwif; |
| 399 | idescsi_pc_t *pc = scsi->pc; | ||
| 399 | struct request *rq = pc->rq; | 400 | struct request *rq = pc->rq; |
| 400 | atapi_bcount_t bcount; | ||
| 401 | atapi_status_t status; | ||
| 402 | atapi_ireason_t ireason; | ||
| 403 | atapi_feature_t feature; | ||
| 404 | |||
| 405 | unsigned int temp; | 401 | unsigned int temp; |
| 402 | u16 bcount; | ||
| 403 | u8 stat, ireason; | ||
| 406 | 404 | ||
| 407 | #if IDESCSI_DEBUG_LOG | 405 | #if IDESCSI_DEBUG_LOG |
| 408 | printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n"); | 406 | printk (KERN_INFO "ide-scsi: Reached idescsi_pc_intr interrupt handler\n"); |
| @@ -425,30 +423,29 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) | |||
| 425 | (void) HWIF(drive)->ide_dma_end(drive); | 423 | (void) HWIF(drive)->ide_dma_end(drive); |
| 426 | } | 424 | } |
| 427 | 425 | ||
| 428 | feature.all = 0; | ||
| 429 | /* Clear the interrupt */ | 426 | /* Clear the interrupt */ |
| 430 | status.all = HWIF(drive)->INB(IDE_STATUS_REG); | 427 | stat = drive->hwif->INB(IDE_STATUS_REG); |
| 431 | 428 | ||
| 432 | if (!status.b.drq) { | 429 | if ((stat & DRQ_STAT) == 0) { |
| 433 | /* No more interrupts */ | 430 | /* No more interrupts */ |
| 434 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) | 431 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) |
| 435 | printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred); | 432 | printk (KERN_INFO "Packet command completed, %d bytes transferred\n", pc->actually_transferred); |
| 436 | local_irq_enable_in_hardirq(); | 433 | local_irq_enable_in_hardirq(); |
| 437 | if (status.b.check) | 434 | if (stat & ERR_STAT) |
| 438 | rq->errors++; | 435 | rq->errors++; |
| 439 | idescsi_end_request (drive, 1, 0); | 436 | idescsi_end_request (drive, 1, 0); |
| 440 | return ide_stopped; | 437 | return ide_stopped; |
| 441 | } | 438 | } |
| 442 | bcount.b.low = HWIF(drive)->INB(IDE_BCOUNTL_REG); | 439 | bcount = (hwif->INB(IDE_BCOUNTH_REG) << 8) | |
| 443 | bcount.b.high = HWIF(drive)->INB(IDE_BCOUNTH_REG); | 440 | hwif->INB(IDE_BCOUNTL_REG); |
| 444 | ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); | 441 | ireason = hwif->INB(IDE_IREASON_REG); |
| 445 | 442 | ||
| 446 | if (ireason.b.cod) { | 443 | if (ireason & CD) { |
| 447 | printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n"); | 444 | printk(KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n"); |
| 448 | return ide_do_reset (drive); | 445 | return ide_do_reset (drive); |
| 449 | } | 446 | } |
| 450 | if (ireason.b.io) { | 447 | if (ireason & IO) { |
| 451 | temp = pc->actually_transferred + bcount.all; | 448 | temp = pc->actually_transferred + bcount; |
| 452 | if (temp > pc->request_transfer) { | 449 | if (temp > pc->request_transfer) { |
| 453 | if (temp > pc->buffer_size) { | 450 | if (temp > pc->buffer_size) { |
| 454 | printk(KERN_ERR "ide-scsi: The scsi wants to " | 451 | printk(KERN_ERR "ide-scsi: The scsi wants to " |
| @@ -461,11 +458,13 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) | |||
| 461 | idescsi_input_buffers(drive, pc, temp); | 458 | idescsi_input_buffers(drive, pc, temp); |
| 462 | else | 459 | else |
| 463 | drive->hwif->atapi_input_bytes(drive, pc->current_position, temp); | 460 | drive->hwif->atapi_input_bytes(drive, pc->current_position, temp); |
| 464 | printk(KERN_ERR "ide-scsi: transferred %d of %d bytes\n", temp, bcount.all); | 461 | printk(KERN_ERR "ide-scsi: transferred" |
| 462 | " %d of %d bytes\n", | ||
| 463 | temp, bcount); | ||
| 465 | } | 464 | } |
| 466 | pc->actually_transferred += temp; | 465 | pc->actually_transferred += temp; |
| 467 | pc->current_position += temp; | 466 | pc->current_position += temp; |
| 468 | idescsi_discard_data(drive, bcount.all - temp); | 467 | idescsi_discard_data(drive, bcount - temp); |
| 469 | ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); | 468 | ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); |
| 470 | return ide_started; | 469 | return ide_started; |
| 471 | } | 470 | } |
| @@ -474,22 +473,24 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) | |||
| 474 | #endif /* IDESCSI_DEBUG_LOG */ | 473 | #endif /* IDESCSI_DEBUG_LOG */ |
| 475 | } | 474 | } |
| 476 | } | 475 | } |
| 477 | if (ireason.b.io) { | 476 | if (ireason & IO) { |
| 478 | clear_bit(PC_WRITING, &pc->flags); | 477 | clear_bit(PC_WRITING, &pc->flags); |
| 479 | if (pc->sg) | 478 | if (pc->sg) |
| 480 | idescsi_input_buffers(drive, pc, bcount.all); | 479 | idescsi_input_buffers(drive, pc, bcount); |
| 481 | else | 480 | else |
| 482 | HWIF(drive)->atapi_input_bytes(drive, pc->current_position, bcount.all); | 481 | hwif->atapi_input_bytes(drive, pc->current_position, |
| 482 | bcount); | ||
| 483 | } else { | 483 | } else { |
| 484 | set_bit(PC_WRITING, &pc->flags); | 484 | set_bit(PC_WRITING, &pc->flags); |
| 485 | if (pc->sg) | 485 | if (pc->sg) |
| 486 | idescsi_output_buffers (drive, pc, bcount.all); | 486 | idescsi_output_buffers(drive, pc, bcount); |
| 487 | else | 487 | else |
| 488 | HWIF(drive)->atapi_output_bytes(drive, pc->current_position, bcount.all); | 488 | hwif->atapi_output_bytes(drive, pc->current_position, |
| 489 | bcount); | ||
| 489 | } | 490 | } |
| 490 | /* Update the current position */ | 491 | /* Update the current position */ |
| 491 | pc->actually_transferred += bcount.all; | 492 | pc->actually_transferred += bcount; |
| 492 | pc->current_position += bcount.all; | 493 | pc->current_position += bcount; |
| 493 | 494 | ||
| 494 | /* And set the interrupt handler again */ | 495 | /* And set the interrupt handler again */ |
| 495 | ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); | 496 | ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), idescsi_expiry); |
| @@ -501,16 +502,16 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) | |||
| 501 | ide_hwif_t *hwif = drive->hwif; | 502 | ide_hwif_t *hwif = drive->hwif; |
| 502 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | 503 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
| 503 | idescsi_pc_t *pc = scsi->pc; | 504 | idescsi_pc_t *pc = scsi->pc; |
| 504 | atapi_ireason_t ireason; | ||
| 505 | ide_startstop_t startstop; | 505 | ide_startstop_t startstop; |
| 506 | u8 ireason; | ||
| 506 | 507 | ||
| 507 | if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { | 508 | if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { |
| 508 | printk(KERN_ERR "ide-scsi: Strange, packet command " | 509 | printk(KERN_ERR "ide-scsi: Strange, packet command " |
| 509 | "initiated yet DRQ isn't asserted\n"); | 510 | "initiated yet DRQ isn't asserted\n"); |
| 510 | return startstop; | 511 | return startstop; |
| 511 | } | 512 | } |
| 512 | ireason.all = HWIF(drive)->INB(IDE_IREASON_REG); | 513 | ireason = hwif->INB(IDE_IREASON_REG); |
| 513 | if (!ireason.b.cod || ireason.b.io) { | 514 | if ((ireason & CD) == 0 || (ireason & IO)) { |
| 514 | printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while " | 515 | printk(KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while " |
| 515 | "issuing a packet command\n"); | 516 | "issuing a packet command\n"); |
| 516 | return ide_do_reset (drive); | 517 | return ide_do_reset (drive); |
| @@ -573,30 +574,26 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) | |||
| 573 | { | 574 | { |
| 574 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | 575 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); |
| 575 | ide_hwif_t *hwif = drive->hwif; | 576 | ide_hwif_t *hwif = drive->hwif; |
| 576 | atapi_feature_t feature; | 577 | u16 bcount; |
| 577 | atapi_bcount_t bcount; | 578 | u8 dma = 0; |
| 578 | 579 | ||
| 579 | scsi->pc=pc; /* Set the current packet command */ | 580 | scsi->pc=pc; /* Set the current packet command */ |
| 580 | pc->actually_transferred=0; /* We haven't transferred any data yet */ | 581 | pc->actually_transferred=0; /* We haven't transferred any data yet */ |
| 581 | pc->current_position=pc->buffer; | 582 | pc->current_position=pc->buffer; |
| 582 | bcount.all = min(pc->request_transfer, 63 * 1024); /* Request to transfer the entire buffer at once */ | 583 | /* Request to transfer the entire buffer at once */ |
| 584 | bcount = min(pc->request_transfer, 63 * 1024); | ||
| 583 | 585 | ||
| 584 | feature.all = 0; | ||
| 585 | if (drive->using_dma && !idescsi_map_sg(drive, pc)) { | 586 | if (drive->using_dma && !idescsi_map_sg(drive, pc)) { |
| 586 | hwif->sg_mapped = 1; | 587 | hwif->sg_mapped = 1; |
| 587 | feature.b.dma = !hwif->dma_setup(drive); | 588 | dma = !hwif->dma_setup(drive); |
| 588 | hwif->sg_mapped = 0; | 589 | hwif->sg_mapped = 0; |
| 589 | } | 590 | } |
| 590 | 591 | ||
| 591 | SELECT_DRIVE(drive); | 592 | SELECT_DRIVE(drive); |
| 592 | if (IDE_CONTROL_REG) | ||
| 593 | HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); | ||
| 594 | 593 | ||
| 595 | HWIF(drive)->OUTB(feature.all, IDE_FEATURE_REG); | 594 | ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK, bcount, dma); |
| 596 | HWIF(drive)->OUTB(bcount.b.high, IDE_BCOUNTH_REG); | ||
| 597 | HWIF(drive)->OUTB(bcount.b.low, IDE_BCOUNTL_REG); | ||
| 598 | 595 | ||
| 599 | if (feature.b.dma) | 596 | if (dma) |
| 600 | set_bit(PC_DMA_OK, &pc->flags); | 597 | set_bit(PC_DMA_OK, &pc->flags); |
| 601 | 598 | ||
| 602 | if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) { | 599 | if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) { |
diff --git a/include/asm-cris/arch-v10/ide.h b/include/asm-cris/arch-v10/ide.h index 78b301ed7b12..ea34e0d0a388 100644 --- a/include/asm-cris/arch-v10/ide.h +++ b/include/asm-cris/arch-v10/ide.h | |||
| @@ -89,11 +89,6 @@ static inline void ide_init_default_hwifs(void) | |||
| 89 | } | 89 | } |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | /* some configuration options we don't need */ | ||
| 93 | |||
| 94 | #undef SUPPORT_VLB_SYNC | ||
| 95 | #define SUPPORT_VLB_SYNC 0 | ||
| 96 | |||
| 97 | #endif /* __KERNEL__ */ | 92 | #endif /* __KERNEL__ */ |
| 98 | 93 | ||
| 99 | #endif /* __ASMCRIS_IDE_H */ | 94 | #endif /* __ASMCRIS_IDE_H */ |
diff --git a/include/asm-cris/arch-v32/ide.h b/include/asm-cris/arch-v32/ide.h index 11296170d057..fb9c3627a5b4 100644 --- a/include/asm-cris/arch-v32/ide.h +++ b/include/asm-cris/arch-v32/ide.h | |||
| @@ -48,11 +48,6 @@ static inline unsigned long ide_default_io_base(int index) | |||
| 48 | return REG_TYPE_CONV(unsigned long, reg_ata_rw_ctrl2, ctrl2); | 48 | return REG_TYPE_CONV(unsigned long, reg_ata_rw_ctrl2, ctrl2); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | /* some configuration options we don't need */ | ||
| 52 | |||
| 53 | #undef SUPPORT_VLB_SYNC | ||
| 54 | #define SUPPORT_VLB_SYNC 0 | ||
| 55 | |||
| 56 | #define IDE_ARCH_ACK_INTR | 51 | #define IDE_ARCH_ACK_INTR |
| 57 | #define ide_ack_intr(hwif) ((hwif)->ack_intr(hwif)) | 52 | #define ide_ack_intr(hwif) ((hwif)->ack_intr(hwif)) |
| 58 | 53 | ||
diff --git a/include/asm-frv/ide.h b/include/asm-frv/ide.h index f0bd2cb250c1..8c9a540d4344 100644 --- a/include/asm-frv/ide.h +++ b/include/asm-frv/ide.h | |||
| @@ -18,12 +18,6 @@ | |||
| 18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
| 19 | #include <asm/irq.h> | 19 | #include <asm/irq.h> |
| 20 | 20 | ||
| 21 | #undef SUPPORT_SLOW_DATA_PORTS | ||
| 22 | #define SUPPORT_SLOW_DATA_PORTS 0 | ||
| 23 | |||
| 24 | #undef SUPPORT_VLB_SYNC | ||
| 25 | #define SUPPORT_VLB_SYNC 0 | ||
| 26 | |||
| 27 | #ifndef MAX_HWIFS | 21 | #ifndef MAX_HWIFS |
| 28 | #define MAX_HWIFS 8 | 22 | #define MAX_HWIFS 8 |
| 29 | #endif | 23 | #endif |
diff --git a/include/asm-powerpc/ide.h b/include/asm-powerpc/ide.h index fd7f5a430f0a..6d50310ecaea 100644 --- a/include/asm-powerpc/ide.h +++ b/include/asm-powerpc/ide.h | |||
| @@ -42,9 +42,6 @@ struct ide_machdep_calls { | |||
| 42 | 42 | ||
| 43 | extern struct ide_machdep_calls ppc_ide_md; | 43 | extern struct ide_machdep_calls ppc_ide_md; |
| 44 | 44 | ||
| 45 | #undef SUPPORT_SLOW_DATA_PORTS | ||
| 46 | #define SUPPORT_SLOW_DATA_PORTS 0 | ||
| 47 | |||
| 48 | #define IDE_ARCH_OBSOLETE_DEFAULTS | 45 | #define IDE_ARCH_OBSOLETE_DEFAULTS |
| 49 | 46 | ||
| 50 | static __inline__ int ide_default_irq(unsigned long base) | 47 | static __inline__ int ide_default_irq(unsigned long base) |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d18ee67b40f8..40ee1706caa3 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -144,7 +144,6 @@ enum rq_cmd_type_bits { | |||
| 144 | * private REQ_LB opcodes to differentiate what type of request this is | 144 | * private REQ_LB opcodes to differentiate what type of request this is |
| 145 | */ | 145 | */ |
| 146 | REQ_TYPE_ATA_CMD, | 146 | REQ_TYPE_ATA_CMD, |
| 147 | REQ_TYPE_ATA_TASK, | ||
| 148 | REQ_TYPE_ATA_TASKFILE, | 147 | REQ_TYPE_ATA_TASKFILE, |
| 149 | REQ_TYPE_ATA_PC, | 148 | REQ_TYPE_ATA_PC, |
| 150 | }; | 149 | }; |
diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h index 818c6afc1091..ff43f8d6b5b3 100644 --- a/include/linux/hdreg.h +++ b/include/linux/hdreg.h | |||
| @@ -44,7 +44,9 @@ | |||
| 44 | 44 | ||
| 45 | /* Bits for HD_ERROR */ | 45 | /* Bits for HD_ERROR */ |
| 46 | #define MARK_ERR 0x01 /* Bad address mark */ | 46 | #define MARK_ERR 0x01 /* Bad address mark */ |
| 47 | #define ILI_ERR 0x01 /* Illegal Length Indication (ATAPI) */ | ||
| 47 | #define TRK0_ERR 0x02 /* couldn't find track 0 */ | 48 | #define TRK0_ERR 0x02 /* couldn't find track 0 */ |
| 49 | #define EOM_ERR 0x02 /* End Of Media (ATAPI) */ | ||
| 48 | #define ABRT_ERR 0x04 /* Command aborted */ | 50 | #define ABRT_ERR 0x04 /* Command aborted */ |
| 49 | #define MCR_ERR 0x08 /* media change request */ | 51 | #define MCR_ERR 0x08 /* media change request */ |
| 50 | #define ID_ERR 0x10 /* ID field not found */ | 52 | #define ID_ERR 0x10 /* ID field not found */ |
| @@ -52,6 +54,7 @@ | |||
| 52 | #define ECC_ERR 0x40 /* Uncorrectable ECC error */ | 54 | #define ECC_ERR 0x40 /* Uncorrectable ECC error */ |
| 53 | #define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ | 55 | #define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ |
| 54 | #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ | 56 | #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ |
| 57 | #define LFS_ERR 0xf0 /* Last Failed Sense (ATAPI) */ | ||
| 55 | 58 | ||
| 56 | /* Bits of HD_NSECTOR */ | 59 | /* Bits of HD_NSECTOR */ |
| 57 | #define CD 0x01 | 60 | #define CD 0x01 |
| @@ -70,13 +73,13 @@ | |||
| 70 | #define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(__u8)) | 73 | #define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(__u8)) |
| 71 | #define HDIO_DRIVE_TASK_HDR_SIZE (8 * sizeof(__u8)) | 74 | #define HDIO_DRIVE_TASK_HDR_SIZE (8 * sizeof(__u8)) |
| 72 | 75 | ||
| 73 | #define IDE_DRIVE_TASK_INVALID -1 | ||
| 74 | #define IDE_DRIVE_TASK_NO_DATA 0 | 76 | #define IDE_DRIVE_TASK_NO_DATA 0 |
| 77 | #ifndef __KERNEL__ | ||
| 78 | #define IDE_DRIVE_TASK_INVALID -1 | ||
| 75 | #define IDE_DRIVE_TASK_SET_XFER 1 | 79 | #define IDE_DRIVE_TASK_SET_XFER 1 |
| 76 | |||
| 77 | #define IDE_DRIVE_TASK_IN 2 | 80 | #define IDE_DRIVE_TASK_IN 2 |
| 78 | |||
| 79 | #define IDE_DRIVE_TASK_OUT 3 | 81 | #define IDE_DRIVE_TASK_OUT 3 |
| 82 | #endif | ||
| 80 | #define IDE_DRIVE_TASK_RAW_WRITE 4 | 83 | #define IDE_DRIVE_TASK_RAW_WRITE 4 |
| 81 | 84 | ||
| 82 | /* | 85 | /* |
| @@ -87,10 +90,10 @@ | |||
| 87 | #ifndef __KERNEL__ | 90 | #ifndef __KERNEL__ |
| 88 | #define IDE_TASKFILE_STD_OUT_FLAGS 0xFE | 91 | #define IDE_TASKFILE_STD_OUT_FLAGS 0xFE |
| 89 | #define IDE_HOB_STD_OUT_FLAGS 0x3C | 92 | #define IDE_HOB_STD_OUT_FLAGS 0x3C |
| 90 | #endif | ||
| 91 | 93 | ||
| 92 | typedef unsigned char task_ioreg_t; | 94 | typedef unsigned char task_ioreg_t; |
| 93 | typedef unsigned long sata_ioreg_t; | 95 | typedef unsigned long sata_ioreg_t; |
| 96 | #endif | ||
| 94 | 97 | ||
| 95 | typedef union ide_reg_valid_s { | 98 | typedef union ide_reg_valid_s { |
| 96 | unsigned all : 16; | 99 | unsigned all : 16; |
| @@ -116,8 +119,8 @@ typedef union ide_reg_valid_s { | |||
| 116 | } ide_reg_valid_t; | 119 | } ide_reg_valid_t; |
| 117 | 120 | ||
| 118 | typedef struct ide_task_request_s { | 121 | typedef struct ide_task_request_s { |
| 119 | task_ioreg_t io_ports[8]; | 122 | __u8 io_ports[8]; |
| 120 | task_ioreg_t hob_ports[8]; | 123 | __u8 hob_ports[8]; /* bytes 6 and 7 are unused */ |
| 121 | ide_reg_valid_t out_flags; | 124 | ide_reg_valid_t out_flags; |
| 122 | ide_reg_valid_t in_flags; | 125 | ide_reg_valid_t in_flags; |
| 123 | int data_phase; | 126 | int data_phase; |
| @@ -133,36 +136,35 @@ typedef struct ide_ioctl_request_s { | |||
| 133 | } ide_ioctl_request_t; | 136 | } ide_ioctl_request_t; |
| 134 | 137 | ||
| 135 | struct hd_drive_cmd_hdr { | 138 | struct hd_drive_cmd_hdr { |
| 136 | task_ioreg_t command; | 139 | __u8 command; |
| 137 | task_ioreg_t sector_number; | 140 | __u8 sector_number; |
| 138 | task_ioreg_t feature; | 141 | __u8 feature; |
| 139 | task_ioreg_t sector_count; | 142 | __u8 sector_count; |
| 140 | }; | 143 | }; |
| 141 | 144 | ||
| 145 | #ifndef __KERNEL__ | ||
| 142 | typedef struct hd_drive_task_hdr { | 146 | typedef struct hd_drive_task_hdr { |
| 143 | task_ioreg_t data; | 147 | __u8 data; |
| 144 | task_ioreg_t feature; | 148 | __u8 feature; |
| 145 | task_ioreg_t sector_count; | 149 | __u8 sector_count; |
| 146 | task_ioreg_t sector_number; | 150 | __u8 sector_number; |
| 147 | task_ioreg_t low_cylinder; | 151 | __u8 low_cylinder; |
| 148 | task_ioreg_t high_cylinder; | 152 | __u8 high_cylinder; |
| 149 | task_ioreg_t device_head; | 153 | __u8 device_head; |
| 150 | task_ioreg_t command; | 154 | __u8 command; |
| 151 | } task_struct_t; | 155 | } task_struct_t; |
| 152 | 156 | ||
| 153 | typedef struct hd_drive_hob_hdr { | 157 | typedef struct hd_drive_hob_hdr { |
| 154 | task_ioreg_t data; | 158 | __u8 data; |
| 155 | task_ioreg_t feature; | 159 | __u8 feature; |
| 156 | task_ioreg_t sector_count; | 160 | __u8 sector_count; |
| 157 | task_ioreg_t sector_number; | 161 | __u8 sector_number; |
| 158 | task_ioreg_t low_cylinder; | 162 | __u8 low_cylinder; |
| 159 | task_ioreg_t high_cylinder; | 163 | __u8 high_cylinder; |
| 160 | task_ioreg_t device_head; | 164 | __u8 device_head; |
| 161 | task_ioreg_t control; | 165 | __u8 control; |
| 162 | } hob_struct_t; | 166 | } hob_struct_t; |
| 163 | 167 | #endif | |
| 164 | #define TASKFILE_INVALID 0x7fff | ||
| 165 | #define TASKFILE_48 0x8000 | ||
| 166 | 168 | ||
| 167 | #define TASKFILE_NO_DATA 0x0000 | 169 | #define TASKFILE_NO_DATA 0x0000 |
| 168 | 170 | ||
| @@ -178,12 +180,16 @@ typedef struct hd_drive_hob_hdr { | |||
| 178 | #define TASKFILE_IN_DMAQ 0x0080 | 180 | #define TASKFILE_IN_DMAQ 0x0080 |
| 179 | #define TASKFILE_OUT_DMAQ 0x0100 | 181 | #define TASKFILE_OUT_DMAQ 0x0100 |
| 180 | 182 | ||
| 183 | #ifndef __KERNEL__ | ||
| 181 | #define TASKFILE_P_IN 0x0200 | 184 | #define TASKFILE_P_IN 0x0200 |
| 182 | #define TASKFILE_P_OUT 0x0400 | 185 | #define TASKFILE_P_OUT 0x0400 |
| 183 | #define TASKFILE_P_IN_DMA 0x0800 | 186 | #define TASKFILE_P_IN_DMA 0x0800 |
| 184 | #define TASKFILE_P_OUT_DMA 0x1000 | 187 | #define TASKFILE_P_OUT_DMA 0x1000 |
| 185 | #define TASKFILE_P_IN_DMAQ 0x2000 | 188 | #define TASKFILE_P_IN_DMAQ 0x2000 |
| 186 | #define TASKFILE_P_OUT_DMAQ 0x4000 | 189 | #define TASKFILE_P_OUT_DMAQ 0x4000 |
| 190 | #define TASKFILE_48 0x8000 | ||
| 191 | #define TASKFILE_INVALID 0x7fff | ||
| 192 | #endif | ||
| 187 | 193 | ||
| 188 | /* ATA/ATAPI Commands pre T13 Spec */ | 194 | /* ATA/ATAPI Commands pre T13 Spec */ |
| 189 | #define WIN_NOP 0x00 | 195 | #define WIN_NOP 0x00 |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 9a6a41e7079f..1e4409937ec3 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -27,25 +27,10 @@ | |||
| 27 | #include <asm/semaphore.h> | 27 | #include <asm/semaphore.h> |
| 28 | #include <asm/mutex.h> | 28 | #include <asm/mutex.h> |
| 29 | 29 | ||
| 30 | /****************************************************************************** | 30 | #if defined(CRIS) || defined(FRV) |
| 31 | * IDE driver configuration options (play with these as desired): | 31 | # define SUPPORT_VLB_SYNC 0 |
| 32 | * | 32 | #else |
| 33 | * REALLY_SLOW_IO can be defined in ide.c and ide-cd.c, if necessary | 33 | # define SUPPORT_VLB_SYNC 1 |
| 34 | */ | ||
| 35 | #define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */ | ||
| 36 | |||
| 37 | #ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */ | ||
| 38 | #define SUPPORT_SLOW_DATA_PORTS 1 /* 0 to reduce kernel size */ | ||
| 39 | #endif | ||
| 40 | #ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */ | ||
| 41 | #define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */ | ||
| 42 | #endif | ||
| 43 | #ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */ | ||
| 44 | #define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */ | ||
| 45 | #endif | ||
| 46 | |||
| 47 | #ifndef DISABLE_IRQ_NOSYNC | ||
| 48 | #define DISABLE_IRQ_NOSYNC 0 | ||
| 49 | #endif | 34 | #endif |
| 50 | 35 | ||
| 51 | /* | 36 | /* |
| @@ -55,10 +40,6 @@ | |||
| 55 | 40 | ||
| 56 | #define IDE_NO_IRQ (-1) | 41 | #define IDE_NO_IRQ (-1) |
| 57 | 42 | ||
| 58 | /* | ||
| 59 | * "No user-serviceable parts" beyond this point :) | ||
| 60 | *****************************************************************************/ | ||
| 61 | |||
| 62 | typedef unsigned char byte; /* used everywhere */ | 43 | typedef unsigned char byte; /* used everywhere */ |
| 63 | 44 | ||
| 64 | /* | 45 | /* |
| @@ -103,8 +84,6 @@ typedef unsigned char byte; /* used everywhere */ | |||
| 103 | #define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET | 84 | #define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET |
| 104 | #define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET | 85 | #define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET |
| 105 | 86 | ||
| 106 | #define IDE_CONTROL_OFFSET_HOB (7) | ||
| 107 | |||
| 108 | #define IDE_DATA_REG (HWIF(drive)->io_ports[IDE_DATA_OFFSET]) | 87 | #define IDE_DATA_REG (HWIF(drive)->io_ports[IDE_DATA_OFFSET]) |
| 109 | #define IDE_ERROR_REG (HWIF(drive)->io_ports[IDE_ERROR_OFFSET]) | 88 | #define IDE_ERROR_REG (HWIF(drive)->io_ports[IDE_ERROR_OFFSET]) |
| 110 | #define IDE_NSECTOR_REG (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET]) | 89 | #define IDE_NSECTOR_REG (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET]) |
| @@ -327,47 +306,16 @@ static inline void ide_init_hwif_ports(hw_regs_t *hw, | |||
| 327 | typedef union { | 306 | typedef union { |
| 328 | unsigned all : 8; | 307 | unsigned all : 8; |
| 329 | struct { | 308 | struct { |
| 330 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
| 331 | unsigned set_geometry : 1; | 309 | unsigned set_geometry : 1; |
| 332 | unsigned recalibrate : 1; | 310 | unsigned recalibrate : 1; |
| 333 | unsigned set_multmode : 1; | 311 | unsigned set_multmode : 1; |
| 334 | unsigned set_tune : 1; | 312 | unsigned set_tune : 1; |
| 335 | unsigned serviced : 1; | 313 | unsigned serviced : 1; |
| 336 | unsigned reserved : 3; | 314 | unsigned reserved : 3; |
| 337 | #elif defined(__BIG_ENDIAN_BITFIELD) | ||
| 338 | unsigned reserved : 3; | ||
| 339 | unsigned serviced : 1; | ||
| 340 | unsigned set_tune : 1; | ||
| 341 | unsigned set_multmode : 1; | ||
| 342 | unsigned recalibrate : 1; | ||
| 343 | unsigned set_geometry : 1; | ||
| 344 | #else | ||
| 345 | #error "Please fix <asm/byteorder.h>" | ||
| 346 | #endif | ||
| 347 | } b; | 315 | } b; |
| 348 | } special_t; | 316 | } special_t; |
| 349 | 317 | ||
| 350 | /* | 318 | /* |
| 351 | * ATA DATA Register Special. | ||
| 352 | * ATA NSECTOR Count Register(). | ||
| 353 | * ATAPI Byte Count Register. | ||
| 354 | */ | ||
| 355 | typedef union { | ||
| 356 | unsigned all :16; | ||
| 357 | struct { | ||
| 358 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
| 359 | unsigned low :8; /* LSB */ | ||
| 360 | unsigned high :8; /* MSB */ | ||
| 361 | #elif defined(__BIG_ENDIAN_BITFIELD) | ||
| 362 | unsigned high :8; /* MSB */ | ||
| 363 | unsigned low :8; /* LSB */ | ||
| 364 | #else | ||
| 365 | #error "Please fix <asm/byteorder.h>" | ||
| 366 | #endif | ||
| 367 | } b; | ||
| 368 | } ata_nsector_t, ata_data_t, atapi_bcount_t; | ||
| 369 | |||
| 370 | /* | ||
| 371 | * ATA-IDE Select Register, aka Device-Head | 319 | * ATA-IDE Select Register, aka Device-Head |
| 372 | * | 320 | * |
| 373 | * head : always zeros here | 321 | * head : always zeros here |
| @@ -398,131 +346,6 @@ typedef union { | |||
| 398 | } select_t, ata_select_t; | 346 | } select_t, ata_select_t; |
| 399 | 347 | ||
| 400 | /* | 348 | /* |
| 401 | * The ATA-IDE Status Register. | ||
| 402 | * The ATAPI Status Register. | ||
| 403 | * | ||
| 404 | * check : Error occurred | ||
| 405 | * idx : Index Error | ||
| 406 | * corr : Correctable error occurred | ||
| 407 | * drq : Data is request by the device | ||
| 408 | * dsc : Disk Seek Complete : ata | ||
| 409 | * : Media access command finished : atapi | ||
| 410 | * df : Device Fault : ata | ||
| 411 | * : Reserved : atapi | ||
| 412 | * drdy : Ready, Command Mode Capable : ata | ||
| 413 | * : Ignored for ATAPI commands : atapi | ||
| 414 | * bsy : Disk is Busy | ||
| 415 | * : The device has access to the command block | ||
| 416 | */ | ||
| 417 | typedef union { | ||
| 418 | unsigned all :8; | ||
| 419 | struct { | ||
| 420 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
| 421 | unsigned check :1; | ||
| 422 | unsigned idx :1; | ||
| 423 | unsigned corr :1; | ||
| 424 | unsigned drq :1; | ||
| 425 | unsigned dsc :1; | ||
| 426 | unsigned df :1; | ||
| 427 | unsigned drdy :1; | ||
| 428 | unsigned bsy :1; | ||
| 429 | #elif defined(__BIG_ENDIAN_BITFIELD) | ||
| 430 | unsigned bsy :1; | ||
| 431 | unsigned drdy :1; | ||
| 432 | unsigned df :1; | ||
| 433 | unsigned dsc :1; | ||
| 434 | unsigned drq :1; | ||
| 435 | unsigned corr :1; | ||
| 436 | unsigned idx :1; | ||
| 437 | unsigned check :1; | ||
| 438 | #else | ||
| 439 | #error "Please fix <asm/byteorder.h>" | ||
| 440 | #endif | ||
| 441 | } b; | ||
| 442 | } ata_status_t, atapi_status_t; | ||
| 443 | |||
| 444 | /* | ||
| 445 | * ATAPI Feature Register | ||
| 446 | * | ||
| 447 | * dma : Using DMA or PIO | ||
| 448 | * reserved321 : Reserved | ||
| 449 | * reserved654 : Reserved (Tag Type) | ||
| 450 | * reserved7 : Reserved | ||
| 451 | */ | ||
| 452 | typedef union { | ||
| 453 | unsigned all :8; | ||
| 454 | struct { | ||
| 455 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
| 456 | unsigned dma :1; | ||
| 457 | unsigned reserved321 :3; | ||
| 458 | unsigned reserved654 :3; | ||
| 459 | unsigned reserved7 :1; | ||
| 460 | #elif defined(__BIG_ENDIAN_BITFIELD) | ||
| 461 | unsigned reserved7 :1; | ||
| 462 | unsigned reserved654 :3; | ||
| 463 | unsigned reserved321 :3; | ||
| 464 | unsigned dma :1; | ||
| 465 | #else | ||
| 466 | #error "Please fix <asm/byteorder.h>" | ||
| 467 | #endif | ||
| 468 | } b; | ||
| 469 | } atapi_feature_t; | ||
| 470 | |||
| 471 | /* | ||
| 472 | * ATAPI Interrupt Reason Register. | ||
| 473 | * | ||
| 474 | * cod : Information transferred is command (1) or data (0) | ||
| 475 | * io : The device requests us to read (1) or write (0) | ||
| 476 | * reserved : Reserved | ||
| 477 | */ | ||
| 478 | typedef union { | ||
| 479 | unsigned all :8; | ||
| 480 | struct { | ||
| 481 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
| 482 | unsigned cod :1; | ||
| 483 | unsigned io :1; | ||
| 484 | unsigned reserved :6; | ||
| 485 | #elif defined(__BIG_ENDIAN_BITFIELD) | ||
| 486 | unsigned reserved :6; | ||
| 487 | unsigned io :1; | ||
| 488 | unsigned cod :1; | ||
| 489 | #else | ||
| 490 | #error "Please fix <asm/byteorder.h>" | ||
| 491 | #endif | ||
| 492 | } b; | ||
| 493 | } atapi_ireason_t; | ||
| 494 | |||
| 495 | /* | ||
| 496 | * The ATAPI error register. | ||
| 497 | * | ||
| 498 | * ili : Illegal Length Indication | ||
| 499 | * eom : End Of Media Detected | ||
| 500 | * abrt : Aborted command - As defined by ATA | ||
| 501 | * mcr : Media Change Requested - As defined by ATA | ||
| 502 | * sense_key : Sense key of the last failed packet command | ||
| 503 | */ | ||
| 504 | typedef union { | ||
| 505 | unsigned all :8; | ||
| 506 | struct { | ||
| 507 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
| 508 | unsigned ili :1; | ||
| 509 | unsigned eom :1; | ||
| 510 | unsigned abrt :1; | ||
| 511 | unsigned mcr :1; | ||
| 512 | unsigned sense_key :4; | ||
| 513 | #elif defined(__BIG_ENDIAN_BITFIELD) | ||
| 514 | unsigned sense_key :4; | ||
| 515 | unsigned mcr :1; | ||
| 516 | unsigned abrt :1; | ||
| 517 | unsigned eom :1; | ||
| 518 | unsigned ili :1; | ||
| 519 | #else | ||
| 520 | #error "Please fix <asm/byteorder.h>" | ||
| 521 | #endif | ||
| 522 | } b; | ||
| 523 | } atapi_error_t; | ||
| 524 | |||
| 525 | /* | ||
| 526 | * Status returned from various ide_ functions | 349 | * Status returned from various ide_ functions |
| 527 | */ | 350 | */ |
| 528 | typedef enum { | 351 | typedef enum { |
| @@ -701,8 +524,6 @@ typedef struct hwif_s { | |||
| 701 | void (*pre_reset)(ide_drive_t *); | 524 | void (*pre_reset)(ide_drive_t *); |
| 702 | /* routine to reset controller after a disk reset */ | 525 | /* routine to reset controller after a disk reset */ |
| 703 | void (*resetproc)(ide_drive_t *); | 526 | void (*resetproc)(ide_drive_t *); |
| 704 | /* special interrupt handling for shared pci interrupts */ | ||
| 705 | void (*intrproc)(ide_drive_t *); | ||
| 706 | /* special host masking for drive selection */ | 527 | /* special host masking for drive selection */ |
| 707 | void (*maskproc)(ide_drive_t *, int); | 528 | void (*maskproc)(ide_drive_t *, int); |
| 708 | /* check host's drive quirk list */ | 529 | /* check host's drive quirk list */ |
| @@ -766,7 +587,6 @@ typedef struct hwif_s { | |||
| 766 | int rqsize; /* max sectors per request */ | 587 | int rqsize; /* max sectors per request */ |
| 767 | int irq; /* our irq number */ | 588 | int irq; /* our irq number */ |
| 768 | 589 | ||
| 769 | unsigned long dma_master; /* reference base addr dmabase */ | ||
| 770 | unsigned long dma_base; /* base addr for dma ports */ | 590 | unsigned long dma_base; /* base addr for dma ports */ |
| 771 | unsigned long dma_command; /* dma command register */ | 591 | unsigned long dma_command; /* dma command register */ |
| 772 | unsigned long dma_vendor1; /* dma vendor 1 register */ | 592 | unsigned long dma_vendor1; /* dma vendor 1 register */ |
| @@ -806,7 +626,6 @@ typedef struct hwif_s { | |||
| 806 | /* | 626 | /* |
| 807 | * internal ide interrupt handler type | 627 | * internal ide interrupt handler type |
| 808 | */ | 628 | */ |
| 809 | typedef ide_startstop_t (ide_pre_handler_t)(ide_drive_t *, struct request *); | ||
| 810 | typedef ide_startstop_t (ide_handler_t)(ide_drive_t *); | 629 | typedef ide_startstop_t (ide_handler_t)(ide_drive_t *); |
| 811 | typedef int (ide_expiry_t)(ide_drive_t *); | 630 | typedef int (ide_expiry_t)(ide_drive_t *); |
| 812 | 631 | ||
| @@ -1020,7 +839,8 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, | |||
| 1020 | 839 | ||
| 1021 | extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry); | 840 | extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry); |
| 1022 | 841 | ||
| 1023 | extern void ide_execute_command(ide_drive_t *, task_ioreg_t cmd, ide_handler_t *, unsigned int, ide_expiry_t *); | 842 | void ide_execute_command(ide_drive_t *, u8, ide_handler_t *, unsigned int, |
| 843 | ide_expiry_t *); | ||
| 1024 | 844 | ||
| 1025 | ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8); | 845 | ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8); |
| 1026 | 846 | ||
| @@ -1062,52 +882,114 @@ extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); | |||
| 1062 | */ | 882 | */ |
| 1063 | extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *); | 883 | extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *); |
| 1064 | 884 | ||
| 885 | enum { | ||
| 886 | IDE_TFLAG_LBA48 = (1 << 0), | ||
| 887 | IDE_TFLAG_NO_SELECT_MASK = (1 << 1), | ||
| 888 | IDE_TFLAG_FLAGGED = (1 << 2), | ||
| 889 | IDE_TFLAG_OUT_DATA = (1 << 3), | ||
| 890 | IDE_TFLAG_OUT_HOB_FEATURE = (1 << 4), | ||
| 891 | IDE_TFLAG_OUT_HOB_NSECT = (1 << 5), | ||
| 892 | IDE_TFLAG_OUT_HOB_LBAL = (1 << 6), | ||
| 893 | IDE_TFLAG_OUT_HOB_LBAM = (1 << 7), | ||
| 894 | IDE_TFLAG_OUT_HOB_LBAH = (1 << 8), | ||
| 895 | IDE_TFLAG_OUT_HOB = IDE_TFLAG_OUT_HOB_FEATURE | | ||
| 896 | IDE_TFLAG_OUT_HOB_NSECT | | ||
| 897 | IDE_TFLAG_OUT_HOB_LBAL | | ||
| 898 | IDE_TFLAG_OUT_HOB_LBAM | | ||
| 899 | IDE_TFLAG_OUT_HOB_LBAH, | ||
| 900 | IDE_TFLAG_OUT_FEATURE = (1 << 9), | ||
| 901 | IDE_TFLAG_OUT_NSECT = (1 << 10), | ||
| 902 | IDE_TFLAG_OUT_LBAL = (1 << 11), | ||
| 903 | IDE_TFLAG_OUT_LBAM = (1 << 12), | ||
| 904 | IDE_TFLAG_OUT_LBAH = (1 << 13), | ||
| 905 | IDE_TFLAG_OUT_TF = IDE_TFLAG_OUT_FEATURE | | ||
| 906 | IDE_TFLAG_OUT_NSECT | | ||
| 907 | IDE_TFLAG_OUT_LBAL | | ||
| 908 | IDE_TFLAG_OUT_LBAM | | ||
| 909 | IDE_TFLAG_OUT_LBAH, | ||
| 910 | IDE_TFLAG_OUT_DEVICE = (1 << 14), | ||
| 911 | IDE_TFLAG_WRITE = (1 << 15), | ||
| 912 | IDE_TFLAG_FLAGGED_SET_IN_FLAGS = (1 << 16), | ||
| 913 | IDE_TFLAG_IN_DATA = (1 << 17), | ||
| 914 | IDE_TFLAG_CUSTOM_HANDLER = (1 << 18), | ||
| 915 | IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 19), | ||
| 916 | IDE_TFLAG_IN_HOB_FEATURE = (1 << 20), | ||
| 917 | IDE_TFLAG_IN_HOB_NSECT = (1 << 21), | ||
| 918 | IDE_TFLAG_IN_HOB_LBAL = (1 << 22), | ||
| 919 | IDE_TFLAG_IN_HOB_LBAM = (1 << 23), | ||
| 920 | IDE_TFLAG_IN_HOB_LBAH = (1 << 24), | ||
| 921 | IDE_TFLAG_IN_HOB_LBA = IDE_TFLAG_IN_HOB_LBAL | | ||
| 922 | IDE_TFLAG_IN_HOB_LBAM | | ||
| 923 | IDE_TFLAG_IN_HOB_LBAH, | ||
| 924 | IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_FEATURE | | ||
| 925 | IDE_TFLAG_IN_HOB_NSECT | | ||
| 926 | IDE_TFLAG_IN_HOB_LBA, | ||
| 927 | IDE_TFLAG_IN_NSECT = (1 << 25), | ||
| 928 | IDE_TFLAG_IN_LBAL = (1 << 26), | ||
| 929 | IDE_TFLAG_IN_LBAM = (1 << 27), | ||
| 930 | IDE_TFLAG_IN_LBAH = (1 << 28), | ||
| 931 | IDE_TFLAG_IN_LBA = IDE_TFLAG_IN_LBAL | | ||
| 932 | IDE_TFLAG_IN_LBAM | | ||
| 933 | IDE_TFLAG_IN_LBAH, | ||
| 934 | IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | | ||
| 935 | IDE_TFLAG_IN_LBA, | ||
| 936 | IDE_TFLAG_IN_DEVICE = (1 << 29), | ||
| 937 | }; | ||
| 938 | |||
| 939 | struct ide_taskfile { | ||
| 940 | u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */ | ||
| 941 | |||
| 942 | u8 hob_feature; /* 1-5: additional data to support LBA48 */ | ||
| 943 | u8 hob_nsect; | ||
| 944 | u8 hob_lbal; | ||
| 945 | u8 hob_lbam; | ||
| 946 | u8 hob_lbah; | ||
| 947 | |||
| 948 | u8 data; /* 6: low data byte (for TASKFILE IOCTL) */ | ||
| 949 | |||
| 950 | union { /* 7: */ | ||
| 951 | u8 error; /* read: error */ | ||
| 952 | u8 feature; /* write: feature */ | ||
| 953 | }; | ||
| 954 | |||
| 955 | u8 nsect; /* 8: number of sectors */ | ||
| 956 | u8 lbal; /* 9: LBA low */ | ||
| 957 | u8 lbam; /* 10: LBA mid */ | ||
| 958 | u8 lbah; /* 11: LBA high */ | ||
| 959 | |||
| 960 | u8 device; /* 12: device select */ | ||
| 961 | |||
| 962 | union { /* 13: */ | ||
| 963 | u8 status; /* read: status */ | ||
| 964 | u8 command; /* write: command */ | ||
| 965 | }; | ||
| 966 | }; | ||
| 967 | |||
| 1065 | typedef struct ide_task_s { | 968 | typedef struct ide_task_s { |
| 1066 | /* | 969 | union { |
| 1067 | * struct hd_drive_task_hdr tf; | 970 | struct ide_taskfile tf; |
| 1068 | * task_struct_t tf; | 971 | u8 tf_array[14]; |
| 1069 | * struct hd_drive_hob_hdr hobf; | 972 | }; |
| 1070 | * hob_struct_t hobf; | 973 | u32 tf_flags; |
| 1071 | */ | ||
| 1072 | task_ioreg_t tfRegister[8]; | ||
| 1073 | task_ioreg_t hobRegister[8]; | ||
| 1074 | ide_reg_valid_t tf_out_flags; | ||
| 1075 | ide_reg_valid_t tf_in_flags; | ||
| 1076 | int data_phase; | 974 | int data_phase; |
| 1077 | int command_type; | ||
| 1078 | ide_pre_handler_t *prehandler; | ||
| 1079 | ide_handler_t *handler; | ||
| 1080 | struct request *rq; /* copy of request */ | 975 | struct request *rq; /* copy of request */ |
| 1081 | void *special; /* valid_t generally */ | 976 | void *special; /* valid_t generally */ |
| 1082 | } ide_task_t; | 977 | } ide_task_t; |
| 1083 | 978 | ||
| 1084 | extern u32 ide_read_24(ide_drive_t *); | 979 | void ide_tf_load(ide_drive_t *, ide_task_t *); |
| 980 | void ide_tf_read(ide_drive_t *, ide_task_t *); | ||
| 1085 | 981 | ||
| 1086 | extern void SELECT_DRIVE(ide_drive_t *); | 982 | extern void SELECT_DRIVE(ide_drive_t *); |
| 1087 | extern void SELECT_INTERRUPT(ide_drive_t *); | ||
| 1088 | extern void SELECT_MASK(ide_drive_t *, int); | 983 | extern void SELECT_MASK(ide_drive_t *, int); |
| 1089 | extern void QUIRK_LIST(ide_drive_t *); | ||
| 1090 | 984 | ||
| 1091 | extern int drive_is_ready(ide_drive_t *); | 985 | extern int drive_is_ready(ide_drive_t *); |
| 1092 | 986 | ||
| 1093 | /* | 987 | void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); |
| 1094 | * taskfile io for disks for now...and builds request from ide_ioctl | ||
| 1095 | */ | ||
| 1096 | extern ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); | ||
| 1097 | |||
| 1098 | /* | ||
| 1099 | * Special Flagged Register Validation Caller | ||
| 1100 | */ | ||
| 1101 | extern ide_startstop_t flagged_taskfile(ide_drive_t *, ide_task_t *); | ||
| 1102 | 988 | ||
| 1103 | extern ide_startstop_t set_multmode_intr(ide_drive_t *); | 989 | ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); |
| 1104 | extern ide_startstop_t set_geometry_intr(ide_drive_t *); | ||
| 1105 | extern ide_startstop_t recal_intr(ide_drive_t *); | ||
| 1106 | extern ide_startstop_t task_no_data_intr(ide_drive_t *); | ||
| 1107 | extern ide_startstop_t task_in_intr(ide_drive_t *); | ||
| 1108 | extern ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); | ||
| 1109 | 990 | ||
| 1110 | extern int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *); | 991 | int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16); |
| 992 | int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); | ||
| 1111 | 993 | ||
| 1112 | int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long); | 994 | int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long); |
| 1113 | int ide_cmd_ioctl(ide_drive_t *, unsigned int, unsigned long); | 995 | int ide_cmd_ioctl(ide_drive_t *, unsigned int, unsigned long); |
| @@ -1212,6 +1094,7 @@ enum { | |||
| 1212 | IDE_HFLAG_IO_32BIT = (1 << 24), | 1094 | IDE_HFLAG_IO_32BIT = (1 << 24), |
| 1213 | /* unmask IRQs */ | 1095 | /* unmask IRQs */ |
| 1214 | IDE_HFLAG_UNMASK_IRQS = (1 << 25), | 1096 | IDE_HFLAG_UNMASK_IRQS = (1 << 25), |
| 1097 | IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26), | ||
| 1215 | }; | 1098 | }; |
| 1216 | 1099 | ||
| 1217 | #ifdef CONFIG_BLK_DEV_OFFBOARD | 1100 | #ifdef CONFIG_BLK_DEV_OFFBOARD |
| @@ -1229,7 +1112,7 @@ struct ide_port_info { | |||
| 1229 | void (*fixup)(ide_hwif_t *); | 1112 | void (*fixup)(ide_hwif_t *); |
| 1230 | ide_pci_enablebit_t enablebits[2]; | 1113 | ide_pci_enablebit_t enablebits[2]; |
| 1231 | hwif_chipset_t chipset; | 1114 | hwif_chipset_t chipset; |
| 1232 | unsigned int extra; | 1115 | u8 extra; |
| 1233 | u32 host_flags; | 1116 | u32 host_flags; |
| 1234 | u8 pio_mask; | 1117 | u8 pio_mask; |
| 1235 | u8 swdma_mask; | 1118 | u8 swdma_mask; |
| @@ -1356,6 +1239,7 @@ static inline int ide_dev_is_sata(struct hd_driveid *id) | |||
| 1356 | return 0; | 1239 | return 0; |
| 1357 | } | 1240 | } |
| 1358 | 1241 | ||
| 1242 | u64 ide_get_lba_addr(struct ide_taskfile *, int); | ||
| 1359 | u8 ide_dump_status(ide_drive_t *, const char *, u8); | 1243 | u8 ide_dump_status(ide_drive_t *, const char *, u8); |
| 1360 | 1244 | ||
| 1361 | typedef struct ide_pio_timings_s { | 1245 | typedef struct ide_pio_timings_s { |
