diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-09 19:43:30 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-09 19:43:30 -0400 |
| commit | 6594d0b1cdfd9058f5b766e490ea1c94ae5e0ed4 (patch) | |
| tree | 042a98424cf6321741bec534d3e3ef240a0bbed5 | |
| parent | 0534c8cb5c8a8a954751fa01eef7831a475a9ec5 (diff) | |
| parent | f0edef8c8b35f04b89311590dd6f1249f07fab3a (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: (27 commits)
xsysace: Fix dereferencing of cf_id after hd_driveid removal
at91_ide: turn on PIO 6 support
at91_ide: remove unused ide_mm_{outb,inb}
ide-cd: reverse NOT_READY sense key logic
ide: refactor tf_read() method
ide: refactor tf_load() method
ide: call write_devctl() method from tf_read() method
ide: move common code out of tf_load() method
ide: simplify 'struct ide_taskfile'
ide: replace IDE_TFLAG_* flags by IDE_VALID_*
ide-cd: fix intendation in cdrom_decode_status()
ide-cd: unify handling of fs and pc requests in cdrom_decode_status()
ide-cd: convert cdrom_decode_status() to use switch statements
ide-cd: update debugging support
ide-cd: respect REQ_QUIET for fs requests in cdrom_decode_status()
ide: remove unused #include <linux/version.h>
tx4939ide: Fix tx4939ide_{in,out}put_data_swap argument
tx493[89]ide: Remove big endian version of tx493[89]ide_tf_{load,read}
ide-cd: carve out an ide_cd_breathe()-helper for fs write requests
ide-cd: move status checking into the IRQ handler
...
| -rw-r--r-- | drivers/block/xsysace.c | 12 | ||||
| -rw-r--r-- | drivers/ide/at91_ide.c | 91 | ||||
| -rw-r--r-- | drivers/ide/falconide.c | 13 | ||||
| -rw-r--r-- | drivers/ide/ide-acpi.c | 5 | ||||
| -rw-r--r-- | drivers/ide/ide-atapi.c | 38 | ||||
| -rw-r--r-- | drivers/ide/ide-cd.c | 288 | ||||
| -rw-r--r-- | drivers/ide/ide-disk.c | 70 | ||||
| -rw-r--r-- | drivers/ide/ide-disk_proc.c | 6 | ||||
| -rw-r--r-- | drivers/ide/ide-dma-sff.c | 9 | ||||
| -rw-r--r-- | drivers/ide/ide-h8300.c | 101 | ||||
| -rw-r--r-- | drivers/ide/ide-io-std.c | 75 | ||||
| -rw-r--r-- | drivers/ide/ide-io.c | 13 | ||||
| -rw-r--r-- | drivers/ide/ide-ioctls.c | 14 | ||||
| -rw-r--r-- | drivers/ide/ide-iops.c | 20 | ||||
| -rw-r--r-- | drivers/ide/ide-lib.c | 28 | ||||
| -rw-r--r-- | drivers/ide/ide-park.c | 3 | ||||
| -rw-r--r-- | drivers/ide/ide-pm.c | 3 | ||||
| -rw-r--r-- | drivers/ide/ide-probe.c | 18 | ||||
| -rw-r--r-- | drivers/ide/ide-proc.c | 4 | ||||
| -rw-r--r-- | drivers/ide/ide-taskfile.c | 97 | ||||
| -rw-r--r-- | drivers/ide/ns87415.c | 34 | ||||
| -rw-r--r-- | drivers/ide/q40ide.c | 14 | ||||
| -rw-r--r-- | drivers/ide/scc_pata.c | 71 | ||||
| -rw-r--r-- | drivers/ide/tx4938ide.c | 89 | ||||
| -rw-r--r-- | drivers/ide/tx4939ide.c | 110 | ||||
| -rw-r--r-- | include/linux/ide.h | 151 |
26 files changed, 461 insertions, 916 deletions
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 6cccdc3f5220..4aecf5dc6a93 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
| @@ -563,7 +563,7 @@ static void ace_fsm_dostate(struct ace_device *ace) | |||
| 563 | case ACE_FSM_STATE_IDENTIFY_PREPARE: | 563 | case ACE_FSM_STATE_IDENTIFY_PREPARE: |
| 564 | /* Send identify command */ | 564 | /* Send identify command */ |
| 565 | ace->fsm_task = ACE_TASK_IDENTIFY; | 565 | ace->fsm_task = ACE_TASK_IDENTIFY; |
| 566 | ace->data_ptr = &ace->cf_id; | 566 | ace->data_ptr = ace->cf_id; |
| 567 | ace->data_count = ACE_BUF_PER_SECTOR; | 567 | ace->data_count = ACE_BUF_PER_SECTOR; |
| 568 | ace_out(ace, ACE_SECCNTCMD, ACE_SECCNTCMD_IDENTIFY); | 568 | ace_out(ace, ACE_SECCNTCMD, ACE_SECCNTCMD_IDENTIFY); |
| 569 | 569 | ||
| @@ -608,8 +608,8 @@ static void ace_fsm_dostate(struct ace_device *ace) | |||
| 608 | break; | 608 | break; |
| 609 | 609 | ||
| 610 | case ACE_FSM_STATE_IDENTIFY_COMPLETE: | 610 | case ACE_FSM_STATE_IDENTIFY_COMPLETE: |
| 611 | ace_fix_driveid(&ace->cf_id[0]); | 611 | ace_fix_driveid(ace->cf_id); |
| 612 | ace_dump_mem(&ace->cf_id, 512); /* Debug: Dump out disk ID */ | 612 | ace_dump_mem(ace->cf_id, 512); /* Debug: Dump out disk ID */ |
| 613 | 613 | ||
| 614 | if (ace->data_result) { | 614 | if (ace->data_result) { |
| 615 | /* Error occured, disable the disk */ | 615 | /* Error occured, disable the disk */ |
| @@ -622,9 +622,9 @@ static void ace_fsm_dostate(struct ace_device *ace) | |||
| 622 | 622 | ||
| 623 | /* Record disk parameters */ | 623 | /* Record disk parameters */ |
| 624 | set_capacity(ace->gd, | 624 | set_capacity(ace->gd, |
| 625 | ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY)); | 625 | ata_id_u32(ace->cf_id, ATA_ID_LBA_CAPACITY)); |
| 626 | dev_info(ace->dev, "capacity: %i sectors\n", | 626 | dev_info(ace->dev, "capacity: %i sectors\n", |
| 627 | ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY)); | 627 | ata_id_u32(ace->cf_id, ATA_ID_LBA_CAPACITY)); |
| 628 | } | 628 | } |
| 629 | 629 | ||
| 630 | /* We're done, drop to IDLE state and notify waiters */ | 630 | /* We're done, drop to IDLE state and notify waiters */ |
| @@ -923,7 +923,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode) | |||
| 923 | static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo) | 923 | static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
| 924 | { | 924 | { |
| 925 | struct ace_device *ace = bdev->bd_disk->private_data; | 925 | struct ace_device *ace = bdev->bd_disk->private_data; |
| 926 | u16 *cf_id = &ace->cf_id[0]; | 926 | u16 *cf_id = ace->cf_id; |
| 927 | 927 | ||
| 928 | dev_dbg(ace->dev, "ace_getgeo()\n"); | 928 | dev_dbg(ace->dev, "ace_getgeo()\n"); |
| 929 | 929 | ||
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c index 8eda552326e9..403d0e4265db 100644 --- a/drivers/ide/at91_ide.c +++ b/drivers/ide/at91_ide.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | * | 20 | * |
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <linux/version.h> | ||
| 24 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
| 25 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 26 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
| @@ -175,90 +174,6 @@ static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, | |||
| 175 | leave_16bit(chipselect, mode); | 174 | leave_16bit(chipselect, mode); |
| 176 | } | 175 | } |
| 177 | 176 | ||
| 178 | static u8 ide_mm_inb(unsigned long port) | ||
| 179 | { | ||
| 180 | return readb((void __iomem *) port); | ||
| 181 | } | ||
| 182 | |||
| 183 | static void ide_mm_outb(u8 value, unsigned long port) | ||
| 184 | { | ||
| 185 | writeb(value, (void __iomem *) port); | ||
| 186 | } | ||
| 187 | |||
| 188 | static void at91_ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) | ||
| 189 | { | ||
| 190 | ide_hwif_t *hwif = drive->hwif; | ||
| 191 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
| 192 | struct ide_taskfile *tf = &cmd->tf; | ||
| 193 | u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | ||
| 194 | |||
| 195 | if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) | ||
| 196 | HIHI = 0xFF; | ||
| 197 | |||
| 198 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
| 199 | ide_mm_outb(tf->hob_feature, io_ports->feature_addr); | ||
| 200 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
| 201 | ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr); | ||
| 202 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
| 203 | ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr); | ||
| 204 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
| 205 | ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr); | ||
| 206 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
| 207 | ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr); | ||
| 208 | |||
| 209 | if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
| 210 | ide_mm_outb(tf->feature, io_ports->feature_addr); | ||
| 211 | if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) | ||
| 212 | ide_mm_outb(tf->nsect, io_ports->nsect_addr); | ||
| 213 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) | ||
| 214 | ide_mm_outb(tf->lbal, io_ports->lbal_addr); | ||
| 215 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) | ||
| 216 | ide_mm_outb(tf->lbam, io_ports->lbam_addr); | ||
| 217 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) | ||
| 218 | ide_mm_outb(tf->lbah, io_ports->lbah_addr); | ||
| 219 | |||
| 220 | if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) | ||
| 221 | ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); | ||
| 222 | } | ||
| 223 | |||
| 224 | static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) | ||
| 225 | { | ||
| 226 | ide_hwif_t *hwif = drive->hwif; | ||
| 227 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
| 228 | struct ide_taskfile *tf = &cmd->tf; | ||
| 229 | |||
| 230 | /* be sure we're looking at the low order bits */ | ||
| 231 | ide_mm_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 232 | |||
| 233 | if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) | ||
| 234 | tf->error = ide_mm_inb(io_ports->feature_addr); | ||
| 235 | if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) | ||
| 236 | tf->nsect = ide_mm_inb(io_ports->nsect_addr); | ||
| 237 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) | ||
| 238 | tf->lbal = ide_mm_inb(io_ports->lbal_addr); | ||
| 239 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) | ||
| 240 | tf->lbam = ide_mm_inb(io_ports->lbam_addr); | ||
| 241 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) | ||
| 242 | tf->lbah = ide_mm_inb(io_ports->lbah_addr); | ||
| 243 | if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
| 244 | tf->device = ide_mm_inb(io_ports->device_addr); | ||
| 245 | |||
| 246 | if (cmd->tf_flags & IDE_TFLAG_LBA48) { | ||
| 247 | ide_mm_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 248 | |||
| 249 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) | ||
| 250 | tf->hob_error = ide_mm_inb(io_ports->feature_addr); | ||
| 251 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
| 252 | tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr); | ||
| 253 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
| 254 | tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr); | ||
| 255 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
| 256 | tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr); | ||
| 257 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
| 258 | tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr); | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) | 177 | static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) |
| 263 | { | 178 | { |
| 264 | struct ide_timing *timing; | 179 | struct ide_timing *timing; |
| @@ -284,8 +199,8 @@ static const struct ide_tp_ops at91_ide_tp_ops = { | |||
| 284 | .write_devctl = ide_write_devctl, | 199 | .write_devctl = ide_write_devctl, |
| 285 | 200 | ||
| 286 | .dev_select = ide_dev_select, | 201 | .dev_select = ide_dev_select, |
| 287 | .tf_load = at91_ide_tf_load, | 202 | .tf_load = ide_tf_load, |
| 288 | .tf_read = at91_ide_tf_read, | 203 | .tf_read = ide_tf_read, |
| 289 | 204 | ||
| 290 | .input_data = at91_ide_input_data, | 205 | .input_data = at91_ide_input_data, |
| 291 | .output_data = at91_ide_output_data, | 206 | .output_data = at91_ide_output_data, |
| @@ -300,7 +215,7 @@ static const struct ide_port_info at91_ide_port_info __initdata = { | |||
| 300 | .tp_ops = &at91_ide_tp_ops, | 215 | .tp_ops = &at91_ide_tp_ops, |
| 301 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE | | 216 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE | |
| 302 | IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS, | 217 | IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS, |
| 303 | .pio_mask = ATA_PIO5, | 218 | .pio_mask = ATA_PIO6, |
| 304 | }; | 219 | }; |
| 305 | 220 | ||
| 306 | /* | 221 | /* |
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c index afa2af9a362b..0e2df6755ec9 100644 --- a/drivers/ide/falconide.c +++ b/drivers/ide/falconide.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <asm/atarihw.h> | 20 | #include <asm/atarihw.h> |
| 21 | #include <asm/atariints.h> | 21 | #include <asm/atariints.h> |
| 22 | #include <asm/atari_stdma.h> | 22 | #include <asm/atari_stdma.h> |
| 23 | #include <asm/ide.h> | ||
| 23 | 24 | ||
| 24 | #define DRV_NAME "falconide" | 25 | #define DRV_NAME "falconide" |
| 25 | 26 | ||
| @@ -67,8 +68,10 @@ static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, | |||
| 67 | { | 68 | { |
| 68 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | 69 | unsigned long data_addr = drive->hwif->io_ports.data_addr; |
| 69 | 70 | ||
| 70 | if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) | 71 | if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) { |
| 71 | return insw(data_addr, buf, (len + 1) / 2); | 72 | __ide_mm_insw(data_addr, buf, (len + 1) / 2); |
| 73 | return; | ||
| 74 | } | ||
| 72 | 75 | ||
| 73 | raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2); | 76 | raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2); |
| 74 | } | 77 | } |
| @@ -78,8 +81,10 @@ static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, | |||
| 78 | { | 81 | { |
| 79 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | 82 | unsigned long data_addr = drive->hwif->io_ports.data_addr; |
| 80 | 83 | ||
| 81 | if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) | 84 | if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) { |
| 82 | return outsw(data_addr, buf, (len + 1) / 2); | 85 | __ide_mm_outsw(data_addr, buf, (len + 1) / 2); |
| 86 | return; | ||
| 87 | } | ||
| 83 | 88 | ||
| 84 | raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2); | 89 | raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2); |
| 85 | } | 90 | } |
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 12f436951bff..77f79d26b264 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
| @@ -318,8 +318,9 @@ static int do_drive_set_taskfiles(ide_drive_t *drive, | |||
| 318 | 318 | ||
| 319 | /* convert GTF to taskfile */ | 319 | /* convert GTF to taskfile */ |
| 320 | memset(&cmd, 0, sizeof(cmd)); | 320 | memset(&cmd, 0, sizeof(cmd)); |
| 321 | memcpy(&cmd.tf_array[7], gtf, REGS_PER_GTF); | 321 | memcpy(&cmd.tf.feature, gtf, REGS_PER_GTF); |
| 322 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 322 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 323 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 323 | 324 | ||
| 324 | err = ide_no_data_taskfile(drive, &cmd); | 325 | err = ide_no_data_taskfile(drive, &cmd); |
| 325 | if (err) { | 326 | if (err) { |
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 3e43b889dd64..7201b176d75b 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
| @@ -254,16 +254,13 @@ EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); | |||
| 254 | 254 | ||
| 255 | void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) | 255 | void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) |
| 256 | { | 256 | { |
| 257 | struct ide_cmd cmd; | 257 | struct ide_taskfile tf; |
| 258 | 258 | ||
| 259 | memset(&cmd, 0, sizeof(cmd)); | 259 | drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT | |
| 260 | cmd.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM | | 260 | IDE_VALID_LBAM | IDE_VALID_LBAH); |
| 261 | IDE_TFLAG_IN_NSECT; | ||
| 262 | 261 | ||
| 263 | drive->hwif->tp_ops->tf_read(drive, &cmd); | 262 | *bcount = (tf.lbah << 8) | tf.lbam; |
| 264 | 263 | *ireason = tf.nsect & 3; | |
| 265 | *bcount = (cmd.tf.lbah << 8) | cmd.tf.lbam; | ||
| 266 | *ireason = cmd.tf.nsect & 3; | ||
| 267 | } | 264 | } |
| 268 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); | 265 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); |
| 269 | 266 | ||
| @@ -439,12 +436,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 439 | return ide_started; | 436 | return ide_started; |
| 440 | } | 437 | } |
| 441 | 438 | ||
| 442 | static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags, | 439 | static void ide_init_packet_cmd(struct ide_cmd *cmd, u8 valid_tf, |
| 443 | u16 bcount, u8 dma) | 440 | u16 bcount, u8 dma) |
| 444 | { | 441 | { |
| 445 | cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO; | 442 | cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO; |
| 446 | cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM | | 443 | cmd->valid.out.tf = IDE_VALID_LBAH | IDE_VALID_LBAM | |
| 447 | IDE_TFLAG_OUT_FEATURE | tf_flags; | 444 | IDE_VALID_FEATURE | valid_tf; |
| 448 | cmd->tf.command = ATA_CMD_PACKET; | 445 | cmd->tf.command = ATA_CMD_PACKET; |
| 449 | cmd->tf.feature = dma; /* Use PIO/DMA */ | 446 | cmd->tf.feature = dma; /* Use PIO/DMA */ |
| 450 | cmd->tf.lbam = bcount & 0xff; | 447 | cmd->tf.lbam = bcount & 0xff; |
| @@ -453,14 +450,11 @@ static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags, | |||
| 453 | 450 | ||
| 454 | static u8 ide_read_ireason(ide_drive_t *drive) | 451 | static u8 ide_read_ireason(ide_drive_t *drive) |
| 455 | { | 452 | { |
| 456 | struct ide_cmd cmd; | 453 | struct ide_taskfile tf; |
| 457 | |||
| 458 | memset(&cmd, 0, sizeof(cmd)); | ||
| 459 | cmd.tf_flags = IDE_TFLAG_IN_NSECT; | ||
| 460 | 454 | ||
| 461 | drive->hwif->tp_ops->tf_read(drive, &cmd); | 455 | drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_NSECT); |
| 462 | 456 | ||
| 463 | return cmd.tf.nsect & 3; | 457 | return tf.nsect & 3; |
| 464 | } | 458 | } |
| 465 | 459 | ||
| 466 | static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) | 460 | static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) |
| @@ -588,12 +582,12 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 588 | ide_expiry_t *expiry = NULL; | 582 | ide_expiry_t *expiry = NULL; |
| 589 | struct request *rq = hwif->rq; | 583 | struct request *rq = hwif->rq; |
| 590 | unsigned int timeout; | 584 | unsigned int timeout; |
| 591 | u32 tf_flags; | ||
| 592 | u16 bcount; | 585 | u16 bcount; |
| 586 | u8 valid_tf; | ||
| 593 | u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT); | 587 | u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT); |
| 594 | 588 | ||
| 595 | if (dev_is_idecd(drive)) { | 589 | if (dev_is_idecd(drive)) { |
| 596 | tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; | 590 | valid_tf = IDE_VALID_NSECT | IDE_VALID_LBAL; |
| 597 | bcount = ide_cd_get_xferlen(rq); | 591 | bcount = ide_cd_get_xferlen(rq); |
| 598 | expiry = ide_cd_expiry; | 592 | expiry = ide_cd_expiry; |
| 599 | timeout = ATAPI_WAIT_PC; | 593 | timeout = ATAPI_WAIT_PC; |
| @@ -607,7 +601,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 607 | pc->xferred = 0; | 601 | pc->xferred = 0; |
| 608 | pc->cur_pos = pc->buf; | 602 | pc->cur_pos = pc->buf; |
| 609 | 603 | ||
| 610 | tf_flags = IDE_TFLAG_OUT_DEVICE; | 604 | valid_tf = IDE_VALID_DEVICE; |
| 611 | bcount = ((drive->media == ide_tape) ? | 605 | bcount = ((drive->media == ide_tape) ? |
| 612 | pc->req_xfer : | 606 | pc->req_xfer : |
| 613 | min(pc->req_xfer, 63 * 1024)); | 607 | min(pc->req_xfer, 63 * 1024)); |
| @@ -627,7 +621,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 627 | : WAIT_TAPE_CMD; | 621 | : WAIT_TAPE_CMD; |
| 628 | } | 622 | } |
| 629 | 623 | ||
| 630 | ide_init_packet_cmd(cmd, tf_flags, bcount, drive->dma); | 624 | ide_init_packet_cmd(cmd, valid_tf, bcount, drive->dma); |
| 631 | 625 | ||
| 632 | (void)do_rw_taskfile(drive, cmd); | 626 | (void)do_rw_taskfile(drive, cmd); |
| 633 | 627 | ||
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 35729a47f797..3aec19d1fdfc 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -265,35 +265,62 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) | |||
| 265 | cdrom_analyze_sense_data(drive, NULL, sense); | 265 | cdrom_analyze_sense_data(drive, NULL, sense); |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | |||
| 268 | /* | 269 | /* |
| 270 | * Allow the drive 5 seconds to recover; some devices will return NOT_READY | ||
| 271 | * while flushing data from cache. | ||
| 272 | * | ||
| 273 | * returns: 0 failed (write timeout expired) | ||
| 274 | * 1 success | ||
| 275 | */ | ||
| 276 | static int ide_cd_breathe(ide_drive_t *drive, struct request *rq) | ||
| 277 | { | ||
| 278 | |||
| 279 | struct cdrom_info *info = drive->driver_data; | ||
| 280 | |||
| 281 | if (!rq->errors) | ||
| 282 | info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY; | ||
| 283 | |||
| 284 | rq->errors = 1; | ||
| 285 | |||
| 286 | if (time_after(jiffies, info->write_timeout)) | ||
| 287 | return 0; | ||
| 288 | else { | ||
| 289 | struct request_queue *q = drive->queue; | ||
| 290 | unsigned long flags; | ||
| 291 | |||
| 292 | /* | ||
| 293 | * take a breather relying on the unplug timer to kick us again | ||
| 294 | */ | ||
| 295 | |||
| 296 | spin_lock_irqsave(q->queue_lock, flags); | ||
| 297 | blk_plug_device(q); | ||
| 298 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
| 299 | |||
| 300 | return 1; | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | /** | ||
| 269 | * Returns: | 305 | * Returns: |
| 270 | * 0: if the request should be continued. | 306 | * 0: if the request should be continued. |
| 271 | * 1: if the request will be going through error recovery. | 307 | * 1: if the request will be going through error recovery. |
| 272 | * 2: if the request should be ended. | 308 | * 2: if the request should be ended. |
| 273 | */ | 309 | */ |
| 274 | static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | 310 | static int cdrom_decode_status(ide_drive_t *drive, u8 stat) |
| 275 | { | 311 | { |
| 276 | ide_hwif_t *hwif = drive->hwif; | 312 | ide_hwif_t *hwif = drive->hwif; |
| 277 | struct request *rq = hwif->rq; | 313 | struct request *rq = hwif->rq; |
| 278 | int stat, err, sense_key; | 314 | int err, sense_key, do_end_request = 0; |
| 279 | 315 | u8 quiet = rq->cmd_flags & REQ_QUIET; | |
| 280 | /* check for errors */ | ||
| 281 | stat = hwif->tp_ops->read_status(hwif); | ||
| 282 | |||
| 283 | if (stat_ret) | ||
| 284 | *stat_ret = stat; | ||
| 285 | |||
| 286 | if (OK_STAT(stat, good_stat, BAD_R_STAT)) | ||
| 287 | return 0; | ||
| 288 | 316 | ||
| 289 | /* get the IDE error register */ | 317 | /* get the IDE error register */ |
| 290 | err = ide_read_error(drive); | 318 | err = ide_read_error(drive); |
| 291 | sense_key = err >> 4; | 319 | sense_key = err >> 4; |
| 292 | 320 | ||
| 293 | ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, " | 321 | ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, " |
| 294 | "rq->cmd_type: 0x%x, err: 0x%x", | 322 | "stat 0x%x", |
| 295 | stat, good_stat, rq->cmd[0], rq->cmd_type, | 323 | rq->cmd[0], rq->cmd_type, err, stat); |
| 296 | err); | ||
| 297 | 324 | ||
| 298 | if (blk_sense_request(rq)) { | 325 | if (blk_sense_request(rq)) { |
| 299 | /* | 326 | /* |
| @@ -303,151 +330,108 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
| 303 | */ | 330 | */ |
| 304 | rq->cmd_flags |= REQ_FAILED; | 331 | rq->cmd_flags |= REQ_FAILED; |
| 305 | return 2; | 332 | return 2; |
| 306 | } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { | 333 | } |
| 307 | /* All other functions, except for READ. */ | ||
| 308 | 334 | ||
| 309 | /* | 335 | /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ |
| 310 | * if we have an error, pass back CHECK_CONDITION as the | 336 | if (blk_pc_request(rq) && !rq->errors) |
| 311 | * scsi status byte | 337 | rq->errors = SAM_STAT_CHECK_CONDITION; |
| 312 | */ | ||
| 313 | if (blk_pc_request(rq) && !rq->errors) | ||
| 314 | rq->errors = SAM_STAT_CHECK_CONDITION; | ||
| 315 | 338 | ||
| 316 | /* check for tray open */ | 339 | if (blk_noretry_request(rq)) |
| 317 | if (sense_key == NOT_READY) { | 340 | do_end_request = 1; |
| 318 | cdrom_saw_media_change(drive); | 341 | |
| 319 | } else if (sense_key == UNIT_ATTENTION) { | 342 | switch (sense_key) { |
| 320 | /* check for media change */ | 343 | case NOT_READY: |
| 344 | if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) { | ||
| 345 | if (ide_cd_breathe(drive, rq)) | ||
| 346 | return 1; | ||
| 347 | } else { | ||
| 321 | cdrom_saw_media_change(drive); | 348 | cdrom_saw_media_change(drive); |
| 322 | return 0; | 349 | |
| 323 | } else if (sense_key == ILLEGAL_REQUEST && | 350 | if (blk_fs_request(rq) && !quiet) |
| 324 | rq->cmd[0] == GPCMD_START_STOP_UNIT) { | 351 | printk(KERN_ERR PFX "%s: tray open\n", |
| 325 | /* | 352 | drive->name); |
| 326 | * Don't print error message for this condition-- | ||
| 327 | * SFF8090i indicates that 5/24/00 is the correct | ||
| 328 | * response to a request to close the tray if the | ||
| 329 | * drive doesn't have that capability. | ||
| 330 | * cdrom_log_sense() knows this! | ||
| 331 | */ | ||
| 332 | } else if (!(rq->cmd_flags & REQ_QUIET)) { | ||
| 333 | /* otherwise, print an error */ | ||
| 334 | ide_dump_status(drive, "packet command error", stat); | ||
| 335 | } | 353 | } |
| 354 | do_end_request = 1; | ||
| 355 | break; | ||
| 356 | case UNIT_ATTENTION: | ||
| 357 | cdrom_saw_media_change(drive); | ||
| 336 | 358 | ||
| 337 | rq->cmd_flags |= REQ_FAILED; | 359 | if (blk_fs_request(rq) == 0) |
| 360 | return 0; | ||
| 338 | 361 | ||
| 339 | /* | 362 | /* |
| 340 | * instead of playing games with moving completions around, | 363 | * Arrange to retry the request but be sure to give up if we've |
| 341 | * remove failed request completely and end it when the | 364 | * retried too many times. |
| 342 | * request sense has completed | ||
| 343 | */ | 365 | */ |
| 344 | goto end_request; | 366 | if (++rq->errors > ERROR_MAX) |
| 345 | |||
| 346 | } else if (blk_fs_request(rq)) { | ||
| 347 | int do_end_request = 0; | ||
| 348 | |||
| 349 | /* handle errors from READ and WRITE requests */ | ||
| 350 | |||
| 351 | if (blk_noretry_request(rq)) | ||
| 352 | do_end_request = 1; | 367 | do_end_request = 1; |
| 353 | 368 | break; | |
| 354 | if (sense_key == NOT_READY) { | 369 | case ILLEGAL_REQUEST: |
| 355 | /* tray open */ | 370 | /* |
| 356 | if (rq_data_dir(rq) == READ) { | 371 | * Don't print error message for this condition -- SFF8090i |
| 357 | cdrom_saw_media_change(drive); | 372 | * indicates that 5/24/00 is the correct response to a request |
| 358 | 373 | * to close the tray if the drive doesn't have that capability. | |
| 359 | /* fail the request */ | 374 | * |
| 360 | printk(KERN_ERR PFX "%s: tray open\n", | 375 | * cdrom_log_sense() knows this! |
| 361 | drive->name); | 376 | */ |
| 362 | do_end_request = 1; | 377 | if (rq->cmd[0] == GPCMD_START_STOP_UNIT) |
| 363 | } else { | 378 | break; |
| 364 | struct cdrom_info *info = drive->driver_data; | 379 | /* fall-through */ |
| 365 | 380 | case DATA_PROTECT: | |
| 366 | /* | 381 | /* |
| 367 | * Allow the drive 5 seconds to recover, some | 382 | * No point in retrying after an illegal request or data |
| 368 | * devices will return this error while flushing | 383 | * protect error. |
| 369 | * data from cache. | 384 | */ |
| 370 | */ | 385 | if (!quiet) |
| 371 | if (!rq->errors) | ||
| 372 | info->write_timeout = jiffies + | ||
| 373 | ATAPI_WAIT_WRITE_BUSY; | ||
| 374 | rq->errors = 1; | ||
| 375 | if (time_after(jiffies, info->write_timeout)) | ||
| 376 | do_end_request = 1; | ||
| 377 | else { | ||
| 378 | struct request_queue *q = drive->queue; | ||
| 379 | unsigned long flags; | ||
| 380 | |||
| 381 | /* | ||
| 382 | * take a breather relying on the unplug | ||
| 383 | * timer to kick us again | ||
| 384 | */ | ||
| 385 | spin_lock_irqsave(q->queue_lock, flags); | ||
| 386 | blk_plug_device(q); | ||
| 387 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
| 388 | |||
| 389 | return 1; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | } else if (sense_key == UNIT_ATTENTION) { | ||
| 393 | /* media change */ | ||
| 394 | cdrom_saw_media_change(drive); | ||
| 395 | |||
| 396 | /* | ||
| 397 | * Arrange to retry the request but be sure to give up | ||
| 398 | * if we've retried too many times. | ||
| 399 | */ | ||
| 400 | if (++rq->errors > ERROR_MAX) | ||
| 401 | do_end_request = 1; | ||
| 402 | } else if (sense_key == ILLEGAL_REQUEST || | ||
| 403 | sense_key == DATA_PROTECT) { | ||
| 404 | /* | ||
| 405 | * No point in retrying after an illegal request or data | ||
| 406 | * protect error. | ||
| 407 | */ | ||
| 408 | ide_dump_status(drive, "command error", stat); | 386 | ide_dump_status(drive, "command error", stat); |
| 409 | do_end_request = 1; | 387 | do_end_request = 1; |
| 410 | } else if (sense_key == MEDIUM_ERROR) { | 388 | break; |
| 411 | /* | 389 | case MEDIUM_ERROR: |
| 412 | * No point in re-trying a zillion times on a bad | 390 | /* |
| 413 | * sector. If we got here the error is not correctable. | 391 | * No point in re-trying a zillion times on a bad sector. |
| 414 | */ | 392 | * If we got here the error is not correctable. |
| 415 | ide_dump_status(drive, "media error (bad sector)", | 393 | */ |
| 394 | if (!quiet) | ||
| 395 | ide_dump_status(drive, "media error " | ||
| 396 | "(bad sector)", stat); | ||
| 397 | do_end_request = 1; | ||
| 398 | break; | ||
| 399 | case BLANK_CHECK: | ||
| 400 | /* disk appears blank? */ | ||
| 401 | if (!quiet) | ||
| 402 | ide_dump_status(drive, "media error (blank)", | ||
| 416 | stat); | 403 | stat); |
| 417 | do_end_request = 1; | 404 | do_end_request = 1; |
| 418 | } else if (sense_key == BLANK_CHECK) { | 405 | break; |
| 419 | /* disk appears blank ?? */ | 406 | default: |
| 420 | ide_dump_status(drive, "media error (blank)", stat); | 407 | if (blk_fs_request(rq) == 0) |
| 421 | do_end_request = 1; | 408 | break; |
| 422 | } else if ((err & ~ATA_ABORTED) != 0) { | 409 | if (err & ~ATA_ABORTED) { |
| 423 | /* go to the default handler for other errors */ | 410 | /* go to the default handler for other errors */ |
| 424 | ide_error(drive, "cdrom_decode_status", stat); | 411 | ide_error(drive, "cdrom_decode_status", stat); |
| 425 | return 1; | 412 | return 1; |
| 426 | } else if ((++rq->errors > ERROR_MAX)) { | 413 | } else if (++rq->errors > ERROR_MAX) |
| 427 | /* we've racked up too many retries, abort */ | 414 | /* we've racked up too many retries, abort */ |
| 428 | do_end_request = 1; | 415 | do_end_request = 1; |
| 429 | } | 416 | } |
| 430 | |||
| 431 | /* | ||
| 432 | * End a request through request sense analysis when we have | ||
| 433 | * sense data. We need this in order to perform end of media | ||
| 434 | * processing. | ||
| 435 | */ | ||
| 436 | if (do_end_request) | ||
| 437 | goto end_request; | ||
| 438 | 417 | ||
| 439 | /* | 418 | if (blk_fs_request(rq) == 0) { |
| 440 | * If we got a CHECK_CONDITION status, queue | 419 | rq->cmd_flags |= REQ_FAILED; |
| 441 | * a request sense command. | 420 | do_end_request = 1; |
| 442 | */ | ||
| 443 | if (stat & ATA_ERR) | ||
| 444 | cdrom_queue_request_sense(drive, NULL, NULL); | ||
| 445 | return 1; | ||
| 446 | } else { | ||
| 447 | blk_dump_rq_flags(rq, PFX "bad rq"); | ||
| 448 | return 2; | ||
| 449 | } | 421 | } |
| 450 | 422 | ||
| 423 | /* | ||
| 424 | * End a request through request sense analysis when we have sense data. | ||
| 425 | * We need this in order to perform end of media processing. | ||
| 426 | */ | ||
| 427 | if (do_end_request) | ||
| 428 | goto end_request; | ||
| 429 | |||
| 430 | /* if we got a CHECK_CONDITION status, queue a request sense command */ | ||
| 431 | if (stat & ATA_ERR) | ||
| 432 | cdrom_queue_request_sense(drive, NULL, NULL); | ||
| 433 | return 1; | ||
| 434 | |||
| 451 | end_request: | 435 | end_request: |
| 452 | if (stat & ATA_ERR) { | 436 | if (stat & ATA_ERR) { |
| 453 | struct request_queue *q = drive->queue; | 437 | struct request_queue *q = drive->queue; |
| @@ -624,15 +608,14 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
| 624 | struct ide_cmd *cmd = &hwif->cmd; | 608 | struct ide_cmd *cmd = &hwif->cmd; |
| 625 | struct request *rq = hwif->rq; | 609 | struct request *rq = hwif->rq; |
| 626 | ide_expiry_t *expiry = NULL; | 610 | ide_expiry_t *expiry = NULL; |
| 627 | int dma_error = 0, dma, stat, thislen, uptodate = 0; | 611 | int dma_error = 0, dma, thislen, uptodate = 0; |
| 628 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors; | 612 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors; |
| 629 | int sense = blk_sense_request(rq); | 613 | int sense = blk_sense_request(rq); |
| 630 | unsigned int timeout; | 614 | unsigned int timeout; |
| 631 | u16 len; | 615 | u16 len; |
| 632 | u8 ireason; | 616 | u8 ireason, stat; |
| 633 | 617 | ||
| 634 | ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x", | 618 | ide_debug_log(IDE_DBG_PC, "cmd: 0x%x, write: 0x%x", rq->cmd[0], write); |
| 635 | rq->cmd[0], write); | ||
| 636 | 619 | ||
| 637 | /* check for errors */ | 620 | /* check for errors */ |
| 638 | dma = drive->dma; | 621 | dma = drive->dma; |
| @@ -648,11 +631,16 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
| 648 | } | 631 | } |
| 649 | } | 632 | } |
| 650 | 633 | ||
| 651 | rc = cdrom_decode_status(drive, 0, &stat); | 634 | /* check status */ |
| 652 | if (rc) { | 635 | stat = hwif->tp_ops->read_status(hwif); |
| 653 | if (rc == 2) | 636 | |
| 654 | goto out_end; | 637 | if (!OK_STAT(stat, 0, BAD_R_STAT)) { |
| 655 | return ide_stopped; | 638 | rc = cdrom_decode_status(drive, stat); |
| 639 | if (rc) { | ||
| 640 | if (rc == 2) | ||
| 641 | goto out_end; | ||
| 642 | return ide_stopped; | ||
| 643 | } | ||
| 656 | } | 644 | } |
| 657 | 645 | ||
| 658 | /* using dma, transfer is complete now */ | 646 | /* using dma, transfer is complete now */ |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index c998cf8e971a..a9fbe2c31210 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
| @@ -97,35 +97,38 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | memset(&cmd, 0, sizeof(cmd)); | 99 | memset(&cmd, 0, sizeof(cmd)); |
| 100 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 100 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 101 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 101 | 102 | ||
| 102 | if (drive->dev_flags & IDE_DFLAG_LBA) { | 103 | if (drive->dev_flags & IDE_DFLAG_LBA) { |
| 103 | if (lba48) { | 104 | if (lba48) { |
| 104 | pr_debug("%s: LBA=0x%012llx\n", drive->name, | 105 | pr_debug("%s: LBA=0x%012llx\n", drive->name, |
| 105 | (unsigned long long)block); | 106 | (unsigned long long)block); |
| 106 | 107 | ||
| 107 | tf->hob_nsect = (nsectors >> 8) & 0xff; | ||
| 108 | tf->hob_lbal = (u8)(block >> 24); | ||
| 109 | if (sizeof(block) != 4) { | ||
| 110 | tf->hob_lbam = (u8)((u64)block >> 32); | ||
| 111 | tf->hob_lbah = (u8)((u64)block >> 40); | ||
| 112 | } | ||
| 113 | |||
| 114 | tf->nsect = nsectors & 0xff; | 108 | tf->nsect = nsectors & 0xff; |
| 115 | tf->lbal = (u8) block; | 109 | tf->lbal = (u8) block; |
| 116 | tf->lbam = (u8)(block >> 8); | 110 | tf->lbam = (u8)(block >> 8); |
| 117 | tf->lbah = (u8)(block >> 16); | 111 | tf->lbah = (u8)(block >> 16); |
| 112 | tf->device = ATA_LBA; | ||
| 118 | 113 | ||
| 119 | cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); | 114 | tf = &cmd.hob; |
| 115 | tf->nsect = (nsectors >> 8) & 0xff; | ||
| 116 | tf->lbal = (u8)(block >> 24); | ||
| 117 | if (sizeof(block) != 4) { | ||
| 118 | tf->lbam = (u8)((u64)block >> 32); | ||
| 119 | tf->lbah = (u8)((u64)block >> 40); | ||
| 120 | } | ||
| 121 | |||
| 122 | cmd.valid.out.hob = IDE_VALID_OUT_HOB; | ||
| 123 | cmd.valid.in.hob = IDE_VALID_IN_HOB; | ||
| 124 | cmd.tf_flags |= IDE_TFLAG_LBA48; | ||
| 120 | } else { | 125 | } else { |
| 121 | tf->nsect = nsectors & 0xff; | 126 | tf->nsect = nsectors & 0xff; |
| 122 | tf->lbal = block; | 127 | tf->lbal = block; |
| 123 | tf->lbam = block >>= 8; | 128 | tf->lbam = block >>= 8; |
| 124 | tf->lbah = block >>= 8; | 129 | tf->lbah = block >>= 8; |
| 125 | tf->device = (block >> 8) & 0xf; | 130 | tf->device = ((block >> 8) & 0xf) | ATA_LBA; |
| 126 | } | 131 | } |
| 127 | |||
| 128 | tf->device |= ATA_LBA; | ||
| 129 | } else { | 132 | } else { |
| 130 | unsigned int sect, head, cyl, track; | 133 | unsigned int sect, head, cyl, track; |
| 131 | 134 | ||
| @@ -220,15 +223,19 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48) | |||
| 220 | tf->command = ATA_CMD_READ_NATIVE_MAX; | 223 | tf->command = ATA_CMD_READ_NATIVE_MAX; |
| 221 | tf->device = ATA_LBA; | 224 | tf->device = ATA_LBA; |
| 222 | 225 | ||
| 223 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 226 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 224 | if (lba48) | 227 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; |
| 225 | cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); | 228 | if (lba48) { |
| 229 | cmd.valid.out.hob = IDE_VALID_OUT_HOB; | ||
| 230 | cmd.valid.in.hob = IDE_VALID_IN_HOB; | ||
| 231 | cmd.tf_flags = IDE_TFLAG_LBA48; | ||
| 232 | } | ||
| 226 | 233 | ||
| 227 | ide_no_data_taskfile(drive, &cmd); | 234 | ide_no_data_taskfile(drive, &cmd); |
| 228 | 235 | ||
| 229 | /* if OK, compute maximum address value */ | 236 | /* if OK, compute maximum address value */ |
| 230 | if (!(tf->status & ATA_ERR)) | 237 | if (!(tf->status & ATA_ERR)) |
| 231 | addr = ide_get_lba_addr(tf, lba48) + 1; | 238 | addr = ide_get_lba_addr(&cmd, lba48) + 1; |
| 232 | 239 | ||
| 233 | return addr; | 240 | return addr; |
| 234 | } | 241 | } |
| @@ -250,9 +257,9 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) | |||
| 250 | tf->lbam = (addr_req >>= 8) & 0xff; | 257 | tf->lbam = (addr_req >>= 8) & 0xff; |
| 251 | tf->lbah = (addr_req >>= 8) & 0xff; | 258 | tf->lbah = (addr_req >>= 8) & 0xff; |
| 252 | if (lba48) { | 259 | if (lba48) { |
| 253 | tf->hob_lbal = (addr_req >>= 8) & 0xff; | 260 | cmd.hob.lbal = (addr_req >>= 8) & 0xff; |
| 254 | tf->hob_lbam = (addr_req >>= 8) & 0xff; | 261 | cmd.hob.lbam = (addr_req >>= 8) & 0xff; |
| 255 | tf->hob_lbah = (addr_req >>= 8) & 0xff; | 262 | cmd.hob.lbah = (addr_req >>= 8) & 0xff; |
| 256 | tf->command = ATA_CMD_SET_MAX_EXT; | 263 | tf->command = ATA_CMD_SET_MAX_EXT; |
| 257 | } else { | 264 | } else { |
| 258 | tf->device = (addr_req >>= 8) & 0x0f; | 265 | tf->device = (addr_req >>= 8) & 0x0f; |
| @@ -260,15 +267,19 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48) | |||
| 260 | } | 267 | } |
| 261 | tf->device |= ATA_LBA; | 268 | tf->device |= ATA_LBA; |
| 262 | 269 | ||
| 263 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 270 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 264 | if (lba48) | 271 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; |
| 265 | cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB); | 272 | if (lba48) { |
| 273 | cmd.valid.out.hob = IDE_VALID_OUT_HOB; | ||
| 274 | cmd.valid.in.hob = IDE_VALID_IN_HOB; | ||
| 275 | cmd.tf_flags = IDE_TFLAG_LBA48; | ||
| 276 | } | ||
| 266 | 277 | ||
| 267 | ide_no_data_taskfile(drive, &cmd); | 278 | ide_no_data_taskfile(drive, &cmd); |
| 268 | 279 | ||
| 269 | /* if OK, compute maximum address value */ | 280 | /* if OK, compute maximum address value */ |
| 270 | if (!(tf->status & ATA_ERR)) | 281 | if (!(tf->status & ATA_ERR)) |
| 271 | addr_set = ide_get_lba_addr(tf, lba48) + 1; | 282 | addr_set = ide_get_lba_addr(&cmd, lba48) + 1; |
| 272 | 283 | ||
| 273 | return addr_set; | 284 | return addr_set; |
| 274 | } | 285 | } |
| @@ -395,8 +406,8 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | |||
| 395 | cmd->tf.command = ATA_CMD_FLUSH_EXT; | 406 | cmd->tf.command = ATA_CMD_FLUSH_EXT; |
| 396 | else | 407 | else |
| 397 | cmd->tf.command = ATA_CMD_FLUSH; | 408 | cmd->tf.command = ATA_CMD_FLUSH; |
| 398 | cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | | 409 | cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 399 | IDE_TFLAG_DYN; | 410 | cmd->tf_flags = IDE_TFLAG_DYN; |
| 400 | cmd->protocol = ATA_PROT_NODATA; | 411 | cmd->protocol = ATA_PROT_NODATA; |
| 401 | 412 | ||
| 402 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; | 413 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; |
| @@ -457,7 +468,8 @@ static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect) | |||
| 457 | cmd.tf.feature = feature; | 468 | cmd.tf.feature = feature; |
| 458 | cmd.tf.nsect = nsect; | 469 | cmd.tf.nsect = nsect; |
| 459 | cmd.tf.command = ATA_CMD_SET_FEATURES; | 470 | cmd.tf.command = ATA_CMD_SET_FEATURES; |
| 460 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 471 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 472 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 461 | 473 | ||
| 462 | return ide_no_data_taskfile(drive, &cmd); | 474 | return ide_no_data_taskfile(drive, &cmd); |
| 463 | } | 475 | } |
| @@ -533,7 +545,8 @@ static int do_idedisk_flushcache(ide_drive_t *drive) | |||
| 533 | cmd.tf.command = ATA_CMD_FLUSH_EXT; | 545 | cmd.tf.command = ATA_CMD_FLUSH_EXT; |
| 534 | else | 546 | else |
| 535 | cmd.tf.command = ATA_CMD_FLUSH; | 547 | cmd.tf.command = ATA_CMD_FLUSH; |
| 536 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 548 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 549 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 537 | 550 | ||
| 538 | return ide_no_data_taskfile(drive, &cmd); | 551 | return ide_no_data_taskfile(drive, &cmd); |
| 539 | } | 552 | } |
| @@ -715,7 +728,8 @@ static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, | |||
| 715 | 728 | ||
| 716 | memset(&cmd, 0, sizeof(cmd)); | 729 | memset(&cmd, 0, sizeof(cmd)); |
| 717 | cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; | 730 | cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; |
| 718 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 731 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 732 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 719 | 733 | ||
| 720 | ret = ide_no_data_taskfile(drive, &cmd); | 734 | ret = ide_no_data_taskfile(drive, &cmd); |
| 721 | 735 | ||
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c index eaea3bef2073..19f263bf0a9e 100644 --- a/drivers/ide/ide-disk_proc.c +++ b/drivers/ide/ide-disk_proc.c | |||
| @@ -13,7 +13,8 @@ static int smart_enable(ide_drive_t *drive) | |||
| 13 | tf->lbam = ATA_SMART_LBAM_PASS; | 13 | tf->lbam = ATA_SMART_LBAM_PASS; |
| 14 | tf->lbah = ATA_SMART_LBAH_PASS; | 14 | tf->lbah = ATA_SMART_LBAH_PASS; |
| 15 | tf->command = ATA_CMD_SMART; | 15 | tf->command = ATA_CMD_SMART; |
| 16 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 16 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 17 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 17 | 18 | ||
| 18 | return ide_no_data_taskfile(drive, &cmd); | 19 | return ide_no_data_taskfile(drive, &cmd); |
| 19 | } | 20 | } |
| @@ -29,7 +30,8 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) | |||
| 29 | tf->lbam = ATA_SMART_LBAM_PASS; | 30 | tf->lbam = ATA_SMART_LBAM_PASS; |
| 30 | tf->lbah = ATA_SMART_LBAH_PASS; | 31 | tf->lbah = ATA_SMART_LBAH_PASS; |
| 31 | tf->command = ATA_CMD_SMART; | 32 | tf->command = ATA_CMD_SMART; |
| 32 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 33 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 34 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 33 | cmd.protocol = ATA_PROT_PIO; | 35 | cmd.protocol = ATA_PROT_PIO; |
| 34 | 36 | ||
| 35 | return ide_raw_taskfile(drive, &cmd, buf, 1); | 37 | return ide_raw_taskfile(drive, &cmd, buf, 1); |
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c index 16fc46edc32d..e4cdf78cc3e9 100644 --- a/drivers/ide/ide-dma-sff.c +++ b/drivers/ide/ide-dma-sff.c | |||
| @@ -277,8 +277,6 @@ void ide_dma_start(ide_drive_t *drive) | |||
| 277 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); | 277 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); |
| 278 | outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD); | 278 | outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD); |
| 279 | } | 279 | } |
| 280 | |||
| 281 | wmb(); | ||
| 282 | } | 280 | } |
| 283 | EXPORT_SYMBOL_GPL(ide_dma_start); | 281 | EXPORT_SYMBOL_GPL(ide_dma_start); |
| 284 | 282 | ||
| @@ -286,7 +284,7 @@ EXPORT_SYMBOL_GPL(ide_dma_start); | |||
| 286 | int ide_dma_end(ide_drive_t *drive) | 284 | int ide_dma_end(ide_drive_t *drive) |
| 287 | { | 285 | { |
| 288 | ide_hwif_t *hwif = drive->hwif; | 286 | ide_hwif_t *hwif = drive->hwif; |
| 289 | u8 dma_stat = 0, dma_cmd = 0, mask; | 287 | u8 dma_stat = 0, dma_cmd = 0; |
| 290 | 288 | ||
| 291 | /* stop DMA */ | 289 | /* stop DMA */ |
| 292 | if (hwif->host_flags & IDE_HFLAG_MMIO) { | 290 | if (hwif->host_flags & IDE_HFLAG_MMIO) { |
| @@ -304,11 +302,10 @@ int ide_dma_end(ide_drive_t *drive) | |||
| 304 | /* clear INTR & ERROR bits */ | 302 | /* clear INTR & ERROR bits */ |
| 305 | ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR); | 303 | ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR); |
| 306 | 304 | ||
| 307 | wmb(); | 305 | #define CHECK_DMA_MASK (ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR) |
| 308 | 306 | ||
| 309 | /* verify good DMA status */ | 307 | /* verify good DMA status */ |
| 310 | mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR; | 308 | if ((dma_stat & CHECK_DMA_MASK) != ATA_DMA_INTR) |
| 311 | if ((dma_stat & mask) != ATA_DMA_INTR) | ||
| 312 | return 0x10 | dma_stat; | 309 | return 0x10 | dma_stat; |
| 313 | return 0; | 310 | return 0; |
| 314 | } | 311 | } |
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c index dac9a6d44963..c06ebdc4a130 100644 --- a/drivers/ide/ide-h8300.c +++ b/drivers/ide/ide-h8300.c | |||
| @@ -22,103 +22,6 @@ | |||
| 22 | (r); \ | 22 | (r); \ |
| 23 | }) | 23 | }) |
| 24 | 24 | ||
| 25 | static void mm_outw(u16 d, unsigned long a) | ||
| 26 | { | ||
| 27 | __asm__("mov.b %w0,r2h\n\t" | ||
| 28 | "mov.b %x0,r2l\n\t" | ||
| 29 | "mov.w r2,@%1" | ||
| 30 | : | ||
| 31 | :"r"(d),"r"(a) | ||
| 32 | :"er2"); | ||
| 33 | } | ||
| 34 | |||
| 35 | static u16 mm_inw(unsigned long a) | ||
| 36 | { | ||
| 37 | register u16 r __asm__("er0"); | ||
| 38 | __asm__("mov.w @%1,r2\n\t" | ||
| 39 | "mov.b r2l,%x0\n\t" | ||
| 40 | "mov.b r2h,%w0" | ||
| 41 | :"=r"(r) | ||
| 42 | :"r"(a) | ||
| 43 | :"er2"); | ||
| 44 | return r; | ||
| 45 | } | ||
| 46 | |||
| 47 | static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) | ||
| 48 | { | ||
| 49 | ide_hwif_t *hwif = drive->hwif; | ||
| 50 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
| 51 | struct ide_taskfile *tf = &cmd->tf; | ||
| 52 | u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | ||
| 53 | |||
| 54 | if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) | ||
| 55 | HIHI = 0xFF; | ||
| 56 | |||
| 57 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
| 58 | outb(tf->hob_feature, io_ports->feature_addr); | ||
| 59 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
| 60 | outb(tf->hob_nsect, io_ports->nsect_addr); | ||
| 61 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
| 62 | outb(tf->hob_lbal, io_ports->lbal_addr); | ||
| 63 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
| 64 | outb(tf->hob_lbam, io_ports->lbam_addr); | ||
| 65 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
| 66 | outb(tf->hob_lbah, io_ports->lbah_addr); | ||
| 67 | |||
| 68 | if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
| 69 | outb(tf->feature, io_ports->feature_addr); | ||
| 70 | if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) | ||
| 71 | outb(tf->nsect, io_ports->nsect_addr); | ||
| 72 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) | ||
| 73 | outb(tf->lbal, io_ports->lbal_addr); | ||
| 74 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) | ||
| 75 | outb(tf->lbam, io_ports->lbam_addr); | ||
| 76 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) | ||
| 77 | outb(tf->lbah, io_ports->lbah_addr); | ||
| 78 | |||
| 79 | if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) | ||
| 80 | outb((tf->device & HIHI) | drive->select, | ||
| 81 | io_ports->device_addr); | ||
| 82 | } | ||
| 83 | |||
| 84 | static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) | ||
| 85 | { | ||
| 86 | ide_hwif_t *hwif = drive->hwif; | ||
| 87 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
| 88 | struct ide_taskfile *tf = &cmd->tf; | ||
| 89 | |||
| 90 | /* be sure we're looking at the low order bits */ | ||
| 91 | outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 92 | |||
| 93 | if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) | ||
| 94 | tf->error = inb(io_ports->feature_addr); | ||
| 95 | if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) | ||
| 96 | tf->nsect = inb(io_ports->nsect_addr); | ||
| 97 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) | ||
| 98 | tf->lbal = inb(io_ports->lbal_addr); | ||
| 99 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) | ||
| 100 | tf->lbam = inb(io_ports->lbam_addr); | ||
| 101 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) | ||
| 102 | tf->lbah = inb(io_ports->lbah_addr); | ||
| 103 | if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
| 104 | tf->device = inb(io_ports->device_addr); | ||
| 105 | |||
| 106 | if (cmd->tf_flags & IDE_TFLAG_LBA48) { | ||
| 107 | outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 108 | |||
| 109 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) | ||
| 110 | tf->hob_error = inb(io_ports->feature_addr); | ||
| 111 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
| 112 | tf->hob_nsect = inb(io_ports->nsect_addr); | ||
| 113 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
| 114 | tf->hob_lbal = inb(io_ports->lbal_addr); | ||
| 115 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
| 116 | tf->hob_lbam = inb(io_ports->lbam_addr); | ||
| 117 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
| 118 | tf->hob_lbah = inb(io_ports->lbah_addr); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | static void mm_outsw(unsigned long addr, void *buf, u32 len) | 25 | static void mm_outsw(unsigned long addr, void *buf, u32 len) |
| 123 | { | 26 | { |
| 124 | unsigned short *bp = (unsigned short *)buf; | 27 | unsigned short *bp = (unsigned short *)buf; |
| @@ -152,8 +55,8 @@ static const struct ide_tp_ops h8300_tp_ops = { | |||
| 152 | .write_devctl = ide_write_devctl, | 55 | .write_devctl = ide_write_devctl, |
| 153 | 56 | ||
| 154 | .dev_select = ide_dev_select, | 57 | .dev_select = ide_dev_select, |
| 155 | .tf_load = h8300_tf_load, | 58 | .tf_load = ide_tf_load, |
| 156 | .tf_read = h8300_tf_read, | 59 | .tf_read = ide_tf_read, |
| 157 | 60 | ||
| 158 | .input_data = h8300_input_data, | 61 | .input_data = h8300_input_data, |
| 159 | .output_data = h8300_output_data, | 62 | .output_data = h8300_output_data, |
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c index 9cac281d82c4..46721c454518 100644 --- a/drivers/ide/ide-io-std.c +++ b/drivers/ide/ide-io-std.c | |||
| @@ -85,98 +85,57 @@ void ide_dev_select(ide_drive_t *drive) | |||
| 85 | } | 85 | } |
| 86 | EXPORT_SYMBOL_GPL(ide_dev_select); | 86 | EXPORT_SYMBOL_GPL(ide_dev_select); |
| 87 | 87 | ||
| 88 | void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) | 88 | void ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) |
| 89 | { | 89 | { |
| 90 | ide_hwif_t *hwif = drive->hwif; | 90 | ide_hwif_t *hwif = drive->hwif; |
| 91 | struct ide_io_ports *io_ports = &hwif->io_ports; | 91 | struct ide_io_ports *io_ports = &hwif->io_ports; |
| 92 | struct ide_taskfile *tf = &cmd->tf; | ||
| 93 | void (*tf_outb)(u8 addr, unsigned long port); | 92 | void (*tf_outb)(u8 addr, unsigned long port); |
| 94 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | 93 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; |
| 95 | u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | ||
| 96 | 94 | ||
| 97 | if (mmio) | 95 | if (mmio) |
| 98 | tf_outb = ide_mm_outb; | 96 | tf_outb = ide_mm_outb; |
| 99 | else | 97 | else |
| 100 | tf_outb = ide_outb; | 98 | tf_outb = ide_outb; |
| 101 | 99 | ||
| 102 | if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) | 100 | if (valid & IDE_VALID_FEATURE) |
| 103 | HIHI = 0xFF; | ||
| 104 | |||
| 105 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
| 106 | tf_outb(tf->hob_feature, io_ports->feature_addr); | ||
| 107 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
| 108 | tf_outb(tf->hob_nsect, io_ports->nsect_addr); | ||
| 109 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
| 110 | tf_outb(tf->hob_lbal, io_ports->lbal_addr); | ||
| 111 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
| 112 | tf_outb(tf->hob_lbam, io_ports->lbam_addr); | ||
| 113 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
| 114 | tf_outb(tf->hob_lbah, io_ports->lbah_addr); | ||
| 115 | |||
| 116 | if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
| 117 | tf_outb(tf->feature, io_ports->feature_addr); | 101 | tf_outb(tf->feature, io_ports->feature_addr); |
| 118 | if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) | 102 | if (valid & IDE_VALID_NSECT) |
| 119 | tf_outb(tf->nsect, io_ports->nsect_addr); | 103 | tf_outb(tf->nsect, io_ports->nsect_addr); |
| 120 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) | 104 | if (valid & IDE_VALID_LBAL) |
| 121 | tf_outb(tf->lbal, io_ports->lbal_addr); | 105 | tf_outb(tf->lbal, io_ports->lbal_addr); |
| 122 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) | 106 | if (valid & IDE_VALID_LBAM) |
| 123 | tf_outb(tf->lbam, io_ports->lbam_addr); | 107 | tf_outb(tf->lbam, io_ports->lbam_addr); |
| 124 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) | 108 | if (valid & IDE_VALID_LBAH) |
| 125 | tf_outb(tf->lbah, io_ports->lbah_addr); | 109 | tf_outb(tf->lbah, io_ports->lbah_addr); |
| 126 | 110 | if (valid & IDE_VALID_DEVICE) | |
| 127 | if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) | 111 | tf_outb(tf->device, io_ports->device_addr); |
| 128 | tf_outb((tf->device & HIHI) | drive->select, | ||
| 129 | io_ports->device_addr); | ||
| 130 | } | 112 | } |
| 131 | EXPORT_SYMBOL_GPL(ide_tf_load); | 113 | EXPORT_SYMBOL_GPL(ide_tf_load); |
| 132 | 114 | ||
| 133 | void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) | 115 | void ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) |
| 134 | { | 116 | { |
| 135 | ide_hwif_t *hwif = drive->hwif; | 117 | ide_hwif_t *hwif = drive->hwif; |
| 136 | struct ide_io_ports *io_ports = &hwif->io_ports; | 118 | struct ide_io_ports *io_ports = &hwif->io_ports; |
| 137 | struct ide_taskfile *tf = &cmd->tf; | ||
| 138 | void (*tf_outb)(u8 addr, unsigned long port); | ||
| 139 | u8 (*tf_inb)(unsigned long port); | 119 | u8 (*tf_inb)(unsigned long port); |
| 140 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | 120 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; |
| 141 | 121 | ||
| 142 | if (mmio) { | 122 | if (mmio) |
| 143 | tf_outb = ide_mm_outb; | ||
| 144 | tf_inb = ide_mm_inb; | 123 | tf_inb = ide_mm_inb; |
| 145 | } else { | 124 | else |
| 146 | tf_outb = ide_outb; | ||
| 147 | tf_inb = ide_inb; | 125 | tf_inb = ide_inb; |
| 148 | } | ||
| 149 | |||
| 150 | /* be sure we're looking at the low order bits */ | ||
| 151 | tf_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 152 | 126 | ||
| 153 | if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) | 127 | if (valid & IDE_VALID_ERROR) |
| 154 | tf->error = tf_inb(io_ports->feature_addr); | 128 | tf->error = tf_inb(io_ports->feature_addr); |
| 155 | if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) | 129 | if (valid & IDE_VALID_NSECT) |
| 156 | tf->nsect = tf_inb(io_ports->nsect_addr); | 130 | tf->nsect = tf_inb(io_ports->nsect_addr); |
| 157 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) | 131 | if (valid & IDE_VALID_LBAL) |
| 158 | tf->lbal = tf_inb(io_ports->lbal_addr); | 132 | tf->lbal = tf_inb(io_ports->lbal_addr); |
| 159 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) | 133 | if (valid & IDE_VALID_LBAM) |
| 160 | tf->lbam = tf_inb(io_ports->lbam_addr); | 134 | tf->lbam = tf_inb(io_ports->lbam_addr); |
| 161 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) | 135 | if (valid & IDE_VALID_LBAH) |
| 162 | tf->lbah = tf_inb(io_ports->lbah_addr); | 136 | tf->lbah = tf_inb(io_ports->lbah_addr); |
| 163 | if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) | 137 | if (valid & IDE_VALID_DEVICE) |
| 164 | tf->device = tf_inb(io_ports->device_addr); | 138 | tf->device = tf_inb(io_ports->device_addr); |
| 165 | |||
| 166 | if (cmd->tf_flags & IDE_TFLAG_LBA48) { | ||
| 167 | tf_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 168 | |||
| 169 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) | ||
| 170 | tf->hob_error = tf_inb(io_ports->feature_addr); | ||
| 171 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
| 172 | tf->hob_nsect = tf_inb(io_ports->nsect_addr); | ||
| 173 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
| 174 | tf->hob_lbal = tf_inb(io_ports->lbal_addr); | ||
| 175 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
| 176 | tf->hob_lbam = tf_inb(io_ports->lbam_addr); | ||
| 177 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
| 178 | tf->hob_lbah = tf_inb(io_ports->lbah_addr); | ||
| 179 | } | ||
| 180 | } | 139 | } |
| 181 | EXPORT_SYMBOL_GPL(ide_tf_read); | 140 | EXPORT_SYMBOL_GPL(ide_tf_read); |
| 182 | 141 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1deb6d29b186..2ae02b8d7f8e 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
| @@ -86,18 +86,18 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err) | |||
| 86 | 86 | ||
| 87 | tp_ops->input_data(drive, cmd, data, 2); | 87 | tp_ops->input_data(drive, cmd, data, 2); |
| 88 | 88 | ||
| 89 | tf->data = data[0]; | 89 | cmd->tf.data = data[0]; |
| 90 | tf->hob_data = data[1]; | 90 | cmd->hob.data = data[1]; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | tp_ops->tf_read(drive, cmd); | 93 | ide_tf_readback(drive, cmd); |
| 94 | 94 | ||
| 95 | if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) && | 95 | if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) && |
| 96 | tf_cmd == ATA_CMD_IDLEIMMEDIATE) { | 96 | tf_cmd == ATA_CMD_IDLEIMMEDIATE) { |
| 97 | if (tf->lbal != 0xc4) { | 97 | if (tf->lbal != 0xc4) { |
| 98 | printk(KERN_ERR "%s: head unload failed!\n", | 98 | printk(KERN_ERR "%s: head unload failed!\n", |
| 99 | drive->name); | 99 | drive->name); |
| 100 | ide_tf_dump(drive->name, tf); | 100 | ide_tf_dump(drive->name, cmd); |
| 101 | } else | 101 | } else |
| 102 | drive->dev_flags |= IDE_DFLAG_PARKED; | 102 | drive->dev_flags |= IDE_DFLAG_PARKED; |
| 103 | } | 103 | } |
| @@ -205,8 +205,9 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) | |||
| 205 | return ide_stopped; | 205 | return ide_stopped; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE | | 208 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 209 | IDE_TFLAG_CUSTOM_HANDLER; | 209 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; |
| 210 | cmd.tf_flags = IDE_TFLAG_CUSTOM_HANDLER; | ||
| 210 | 211 | ||
| 211 | do_rw_taskfile(drive, &cmd); | 212 | do_rw_taskfile(drive, &cmd); |
| 212 | 213 | ||
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index 770142767437..c1c25ebbaa1f 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c | |||
| @@ -141,11 +141,12 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) | |||
| 141 | tf->lbal = args[1]; | 141 | tf->lbal = args[1]; |
| 142 | tf->lbam = 0x4f; | 142 | tf->lbam = 0x4f; |
| 143 | tf->lbah = 0xc2; | 143 | tf->lbah = 0xc2; |
| 144 | cmd.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT; | 144 | cmd.valid.out.tf = IDE_VALID_OUT_TF; |
| 145 | cmd.valid.in.tf = IDE_VALID_NSECT; | ||
| 145 | } else { | 146 | } else { |
| 146 | tf->nsect = args[1]; | 147 | tf->nsect = args[1]; |
| 147 | cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | | 148 | cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT; |
| 148 | IDE_TFLAG_IN_NSECT; | 149 | cmd.valid.in.tf = IDE_VALID_NSECT; |
| 149 | } | 150 | } |
| 150 | tf->command = args[0]; | 151 | tf->command = args[0]; |
| 151 | cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA; | 152 | cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA; |
| @@ -205,14 +206,15 @@ static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg) | |||
| 205 | return -EFAULT; | 206 | return -EFAULT; |
| 206 | 207 | ||
| 207 | memset(&cmd, 0, sizeof(cmd)); | 208 | memset(&cmd, 0, sizeof(cmd)); |
| 208 | memcpy(&cmd.tf_array[7], &args[1], 6); | 209 | memcpy(&cmd.tf.feature, &args[1], 6); |
| 209 | cmd.tf.command = args[0]; | 210 | cmd.tf.command = args[0]; |
| 210 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 211 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 212 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 211 | 213 | ||
| 212 | err = ide_no_data_taskfile(drive, &cmd); | 214 | err = ide_no_data_taskfile(drive, &cmd); |
| 213 | 215 | ||
| 214 | args[0] = cmd.tf.command; | 216 | args[0] = cmd.tf.command; |
| 215 | memcpy(&args[1], &cmd.tf_array[7], 6); | 217 | memcpy(&args[1], &cmd.tf.feature, 6); |
| 216 | 218 | ||
| 217 | if (copy_to_user(p, args, 7)) | 219 | if (copy_to_user(p, args, 7)) |
| 218 | err = -EFAULT; | 220 | err = -EFAULT; |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 27bb70ddd459..c19a221b1e18 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
| @@ -37,14 +37,11 @@ void SELECT_MASK(ide_drive_t *drive, int mask) | |||
| 37 | 37 | ||
| 38 | u8 ide_read_error(ide_drive_t *drive) | 38 | u8 ide_read_error(ide_drive_t *drive) |
| 39 | { | 39 | { |
| 40 | struct ide_cmd cmd; | 40 | struct ide_taskfile tf; |
| 41 | 41 | ||
| 42 | memset(&cmd, 0, sizeof(cmd)); | 42 | drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_ERROR); |
| 43 | cmd.tf_flags = IDE_TFLAG_IN_ERROR; | ||
| 44 | 43 | ||
| 45 | drive->hwif->tp_ops->tf_read(drive, &cmd); | 44 | return tf.error; |
| 46 | |||
| 47 | return cmd.tf.error; | ||
| 48 | } | 45 | } |
| 49 | EXPORT_SYMBOL_GPL(ide_read_error); | 46 | EXPORT_SYMBOL_GPL(ide_read_error); |
| 50 | 47 | ||
| @@ -312,10 +309,10 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
| 312 | { | 309 | { |
| 313 | ide_hwif_t *hwif = drive->hwif; | 310 | ide_hwif_t *hwif = drive->hwif; |
| 314 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 311 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
| 312 | struct ide_taskfile tf; | ||
| 315 | u16 *id = drive->id, i; | 313 | u16 *id = drive->id, i; |
| 316 | int error = 0; | 314 | int error = 0; |
| 317 | u8 stat; | 315 | u8 stat; |
| 318 | struct ide_cmd cmd; | ||
| 319 | 316 | ||
| 320 | #ifdef CONFIG_BLK_DEV_IDEDMA | 317 | #ifdef CONFIG_BLK_DEV_IDEDMA |
| 321 | if (hwif->dma_ops) /* check if host supports DMA */ | 318 | if (hwif->dma_ops) /* check if host supports DMA */ |
| @@ -347,12 +344,11 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
| 347 | udelay(1); | 344 | udelay(1); |
| 348 | tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); | 345 | tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS); |
| 349 | 346 | ||
| 350 | memset(&cmd, 0, sizeof(cmd)); | 347 | memset(&tf, 0, sizeof(tf)); |
| 351 | cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT; | 348 | tf.feature = SETFEATURES_XFER; |
| 352 | cmd.tf.feature = SETFEATURES_XFER; | 349 | tf.nsect = speed; |
| 353 | cmd.tf.nsect = speed; | ||
| 354 | 350 | ||
| 355 | tp_ops->tf_load(drive, &cmd); | 351 | tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE | IDE_VALID_NSECT); |
| 356 | 352 | ||
| 357 | tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES); | 353 | tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES); |
| 358 | 354 | ||
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 217b7fdf2b17..56ff8c46c7d1 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
| @@ -49,16 +49,17 @@ static void ide_dump_opcode(ide_drive_t *drive) | |||
| 49 | printk(KERN_CONT "0x%02x\n", cmd->tf.command); | 49 | printk(KERN_CONT "0x%02x\n", cmd->tf.command); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48) | 52 | u64 ide_get_lba_addr(struct ide_cmd *cmd, int lba48) |
| 53 | { | 53 | { |
| 54 | struct ide_taskfile *tf = &cmd->tf; | ||
| 54 | u32 high, low; | 55 | u32 high, low; |
| 55 | 56 | ||
| 56 | if (lba48) | ||
| 57 | high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | | ||
| 58 | tf->hob_lbal; | ||
| 59 | else | ||
| 60 | high = tf->device & 0xf; | ||
| 61 | low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; | 57 | low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; |
| 58 | if (lba48) { | ||
| 59 | tf = &cmd->hob; | ||
| 60 | high = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal; | ||
| 61 | } else | ||
| 62 | high = tf->device & 0xf; | ||
| 62 | 63 | ||
| 63 | return ((u64)high << 24) | low; | 64 | return ((u64)high << 24) | low; |
| 64 | } | 65 | } |
| @@ -71,17 +72,18 @@ static void ide_dump_sector(ide_drive_t *drive) | |||
| 71 | u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); | 72 | u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); |
| 72 | 73 | ||
| 73 | memset(&cmd, 0, sizeof(cmd)); | 74 | memset(&cmd, 0, sizeof(cmd)); |
| 74 | if (lba48) | 75 | if (lba48) { |
| 75 | cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA | | 76 | cmd.valid.in.tf = IDE_VALID_LBA; |
| 76 | IDE_TFLAG_LBA48; | 77 | cmd.valid.in.hob = IDE_VALID_LBA; |
| 77 | else | 78 | cmd.tf_flags = IDE_TFLAG_LBA48; |
| 78 | cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE; | 79 | } else |
| 80 | cmd.valid.in.tf = IDE_VALID_LBA | IDE_VALID_DEVICE; | ||
| 79 | 81 | ||
| 80 | drive->hwif->tp_ops->tf_read(drive, &cmd); | 82 | ide_tf_readback(drive, &cmd); |
| 81 | 83 | ||
| 82 | if (lba48 || (tf->device & ATA_LBA)) | 84 | if (lba48 || (tf->device & ATA_LBA)) |
| 83 | printk(KERN_CONT ", LBAsect=%llu", | 85 | printk(KERN_CONT ", LBAsect=%llu", |
| 84 | (unsigned long long)ide_get_lba_addr(tf, lba48)); | 86 | (unsigned long long)ide_get_lba_addr(&cmd, lba48)); |
| 85 | else | 87 | else |
| 86 | printk(KERN_CONT ", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam, | 88 | printk(KERN_CONT ", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam, |
| 87 | tf->device & 0xf, tf->lbal); | 89 | tf->device & 0xf, tf->lbal); |
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 9490b446519f..310d03f2b5b7 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c | |||
| @@ -74,7 +74,8 @@ ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq) | |||
| 74 | tf->lbal = 0x4c; | 74 | tf->lbal = 0x4c; |
| 75 | tf->lbam = 0x4e; | 75 | tf->lbam = 0x4e; |
| 76 | tf->lbah = 0x55; | 76 | tf->lbah = 0x55; |
| 77 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 77 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 78 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 78 | } else /* cmd == REQ_UNPARK_HEADS */ | 79 | } else /* cmd == REQ_UNPARK_HEADS */ |
| 79 | tf->command = ATA_CMD_CHK_POWER; | 80 | tf->command = ATA_CMD_CHK_POWER; |
| 80 | 81 | ||
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index bb7858ebb7d1..0d8a151c0a01 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c | |||
| @@ -163,7 +163,8 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) | |||
| 163 | return ide_stopped; | 163 | return ide_stopped; |
| 164 | 164 | ||
| 165 | out_do_tf: | 165 | out_do_tf: |
| 166 | cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 166 | cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 167 | cmd->valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 167 | cmd->protocol = ATA_PROT_NODATA; | 168 | cmd->protocol = ATA_PROT_NODATA; |
| 168 | 169 | ||
| 169 | return do_rw_taskfile(drive, cmd); | 170 | return do_rw_taskfile(drive, cmd); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index d8c1c3e735bb..7f264ed1141b 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
| @@ -283,13 +283,11 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id) | |||
| 283 | * identify command to be sure of reply | 283 | * identify command to be sure of reply |
| 284 | */ | 284 | */ |
| 285 | if (cmd == ATA_CMD_ID_ATAPI) { | 285 | if (cmd == ATA_CMD_ID_ATAPI) { |
| 286 | struct ide_cmd cmd; | 286 | struct ide_taskfile tf; |
| 287 | 287 | ||
| 288 | memset(&cmd, 0, sizeof(cmd)); | 288 | memset(&tf, 0, sizeof(tf)); |
| 289 | /* disable DMA & overlap */ | 289 | /* disable DMA & overlap */ |
| 290 | cmd.tf_flags = IDE_TFLAG_OUT_FEATURE; | 290 | tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE); |
| 291 | |||
| 292 | tp_ops->tf_load(drive, &cmd); | ||
| 293 | } | 291 | } |
| 294 | 292 | ||
| 295 | /* ask drive for ID */ | 293 | /* ask drive for ID */ |
| @@ -337,14 +335,11 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus) | |||
| 337 | 335 | ||
| 338 | static u8 ide_read_device(ide_drive_t *drive) | 336 | static u8 ide_read_device(ide_drive_t *drive) |
| 339 | { | 337 | { |
| 340 | struct ide_cmd cmd; | 338 | struct ide_taskfile tf; |
| 341 | |||
| 342 | memset(&cmd, 0, sizeof(cmd)); | ||
| 343 | cmd.tf_flags = IDE_TFLAG_IN_DEVICE; | ||
| 344 | 339 | ||
| 345 | drive->hwif->tp_ops->tf_read(drive, &cmd); | 340 | drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_DEVICE); |
| 346 | 341 | ||
| 347 | return cmd.tf.device; | 342 | return tf.device; |
| 348 | } | 343 | } |
| 349 | 344 | ||
| 350 | /** | 345 | /** |
| @@ -1314,6 +1309,7 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) | |||
| 1314 | host->get_lock = d->get_lock; | 1309 | host->get_lock = d->get_lock; |
| 1315 | host->release_lock = d->release_lock; | 1310 | host->release_lock = d->release_lock; |
| 1316 | host->host_flags = d->host_flags; | 1311 | host->host_flags = d->host_flags; |
| 1312 | host->irq_flags = d->irq_flags; | ||
| 1317 | } | 1313 | } |
| 1318 | 1314 | ||
| 1319 | return host; | 1315 | return host; |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 10a88bf3eefa..3242698832a4 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
| @@ -204,8 +204,8 @@ static int set_xfer_rate (ide_drive_t *drive, int arg) | |||
| 204 | cmd.tf.command = ATA_CMD_SET_FEATURES; | 204 | cmd.tf.command = ATA_CMD_SET_FEATURES; |
| 205 | cmd.tf.feature = SETFEATURES_XFER; | 205 | cmd.tf.feature = SETFEATURES_XFER; |
| 206 | cmd.tf.nsect = (u8)arg; | 206 | cmd.tf.nsect = (u8)arg; |
| 207 | cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT | | 207 | cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT; |
| 208 | IDE_TFLAG_IN_NSECT; | 208 | cmd.valid.in.tf = IDE_VALID_NSECT; |
| 209 | 209 | ||
| 210 | err = ide_no_data_taskfile(drive, &cmd); | 210 | err = ide_no_data_taskfile(drive, &cmd); |
| 211 | 211 | ||
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 243421ce40d0..4aa6223c11be 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
| @@ -23,17 +23,33 @@ | |||
| 23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
| 24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
| 25 | 25 | ||
| 26 | void ide_tf_dump(const char *s, struct ide_taskfile *tf) | 26 | void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd) |
| 27 | { | ||
| 28 | ide_hwif_t *hwif = drive->hwif; | ||
| 29 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
| 30 | |||
| 31 | /* Be sure we're looking at the low order bytes */ | ||
| 32 | tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); | ||
| 33 | |||
| 34 | tp_ops->tf_read(drive, &cmd->tf, cmd->valid.in.tf); | ||
| 35 | |||
| 36 | if (cmd->tf_flags & IDE_TFLAG_LBA48) { | ||
| 37 | tp_ops->write_devctl(hwif, ATA_HOB | ATA_DEVCTL_OBS); | ||
| 38 | |||
| 39 | tp_ops->tf_read(drive, &cmd->hob, cmd->valid.in.hob); | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | void ide_tf_dump(const char *s, struct ide_cmd *cmd) | ||
| 27 | { | 44 | { |
| 28 | #ifdef DEBUG | 45 | #ifdef DEBUG |
| 29 | printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x " | 46 | printk("%s: tf: feat 0x%02x nsect 0x%02x lbal 0x%02x " |
| 30 | "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n", | 47 | "lbam 0x%02x lbah 0x%02x dev 0x%02x cmd 0x%02x\n", |
| 31 | s, tf->feature, tf->nsect, tf->lbal, | 48 | s, cmd->tf.feature, cmd->tf.nsect, |
| 32 | tf->lbam, tf->lbah, tf->device, tf->command); | 49 | cmd->tf.lbal, cmd->tf.lbam, cmd->tf.lbah, |
| 33 | printk("%s: hob: nsect 0x%02x lbal 0x%02x " | 50 | cmd->tf.device, cmd->tf.command); |
| 34 | "lbam 0x%02x lbah 0x%02x\n", | 51 | printk("%s: hob: nsect 0x%02x lbal 0x%02x lbam 0x%02x lbah 0x%02x\n", |
| 35 | s, tf->hob_nsect, tf->hob_lbal, | 52 | s, cmd->hob.nsect, cmd->hob.lbal, cmd->hob.lbam, cmd->hob.lbah); |
| 36 | tf->hob_lbam, tf->hob_lbah); | ||
| 37 | #endif | 53 | #endif |
| 38 | } | 54 | } |
| 39 | 55 | ||
| @@ -47,7 +63,8 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | |||
| 47 | cmd.tf.command = ATA_CMD_ID_ATA; | 63 | cmd.tf.command = ATA_CMD_ID_ATA; |
| 48 | else | 64 | else |
| 49 | cmd.tf.command = ATA_CMD_ID_ATAPI; | 65 | cmd.tf.command = ATA_CMD_ID_ATAPI; |
| 50 | cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 66 | cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; |
| 67 | cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; | ||
| 51 | cmd.protocol = ATA_PROT_PIO; | 68 | cmd.protocol = ATA_PROT_PIO; |
| 52 | 69 | ||
| 53 | return ide_raw_taskfile(drive, &cmd, buf, 1); | 70 | return ide_raw_taskfile(drive, &cmd, buf, 1); |
| @@ -79,16 +96,27 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) | |||
| 79 | memcpy(cmd, orig_cmd, sizeof(*cmd)); | 96 | memcpy(cmd, orig_cmd, sizeof(*cmd)); |
| 80 | 97 | ||
| 81 | if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { | 98 | if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) { |
| 82 | ide_tf_dump(drive->name, tf); | 99 | ide_tf_dump(drive->name, cmd); |
| 83 | tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); | 100 | tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); |
| 84 | SELECT_MASK(drive, 0); | 101 | SELECT_MASK(drive, 0); |
| 85 | 102 | ||
| 86 | if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) { | 103 | if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) { |
| 87 | u8 data[2] = { tf->data, tf->hob_data }; | 104 | u8 data[2] = { cmd->tf.data, cmd->hob.data }; |
| 88 | 105 | ||
| 89 | tp_ops->output_data(drive, cmd, data, 2); | 106 | tp_ops->output_data(drive, cmd, data, 2); |
| 90 | } | 107 | } |
| 91 | tp_ops->tf_load(drive, cmd); | 108 | |
| 109 | if (cmd->valid.out.tf & IDE_VALID_DEVICE) { | ||
| 110 | u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? | ||
| 111 | 0xE0 : 0xEF; | ||
| 112 | |||
| 113 | if (!(cmd->ftf_flags & IDE_FTFLAG_FLAGGED)) | ||
| 114 | cmd->tf.device &= HIHI; | ||
| 115 | cmd->tf.device |= drive->select; | ||
| 116 | } | ||
| 117 | |||
| 118 | tp_ops->tf_load(drive, &cmd->hob, cmd->valid.out.hob); | ||
| 119 | tp_ops->tf_load(drive, &cmd->tf, cmd->valid.out.tf); | ||
| 92 | } | 120 | } |
| 93 | 121 | ||
| 94 | switch (cmd->protocol) { | 122 | switch (cmd->protocol) { |
| @@ -489,16 +517,17 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) | |||
| 489 | 517 | ||
| 490 | memset(&cmd, 0, sizeof(cmd)); | 518 | memset(&cmd, 0, sizeof(cmd)); |
| 491 | 519 | ||
| 492 | memcpy(&cmd.tf_array[0], req_task->hob_ports, | 520 | memcpy(&cmd.hob, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2); |
| 493 | HDIO_DRIVE_HOB_HDR_SIZE - 2); | 521 | memcpy(&cmd.tf, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); |
| 494 | memcpy(&cmd.tf_array[6], req_task->io_ports, | ||
| 495 | HDIO_DRIVE_TASK_HDR_SIZE); | ||
| 496 | 522 | ||
| 497 | cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | | 523 | cmd.valid.out.tf = IDE_VALID_DEVICE; |
| 498 | IDE_TFLAG_IN_TF; | 524 | cmd.valid.in.tf = IDE_VALID_DEVICE | IDE_VALID_IN_TF; |
| 525 | cmd.tf_flags = IDE_TFLAG_IO_16BIT; | ||
| 499 | 526 | ||
| 500 | if (drive->dev_flags & IDE_DFLAG_LBA48) | 527 | if (drive->dev_flags & IDE_DFLAG_LBA48) { |
| 501 | cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB); | 528 | cmd.tf_flags |= IDE_TFLAG_LBA48; |
| 529 | cmd.valid.in.hob = IDE_VALID_IN_HOB; | ||
| 530 | } | ||
| 502 | 531 | ||
| 503 | if (req_task->out_flags.all) { | 532 | if (req_task->out_flags.all) { |
| 504 | cmd.ftf_flags |= IDE_FTFLAG_FLAGGED; | 533 | cmd.ftf_flags |= IDE_FTFLAG_FLAGGED; |
| @@ -507,28 +536,28 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) | |||
| 507 | cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA; | 536 | cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA; |
| 508 | 537 | ||
| 509 | if (req_task->out_flags.b.nsector_hob) | 538 | if (req_task->out_flags.b.nsector_hob) |
| 510 | cmd.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT; | 539 | cmd.valid.out.hob |= IDE_VALID_NSECT; |
| 511 | if (req_task->out_flags.b.sector_hob) | 540 | if (req_task->out_flags.b.sector_hob) |
| 512 | cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL; | 541 | cmd.valid.out.hob |= IDE_VALID_LBAL; |
| 513 | if (req_task->out_flags.b.lcyl_hob) | 542 | if (req_task->out_flags.b.lcyl_hob) |
| 514 | cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM; | 543 | cmd.valid.out.hob |= IDE_VALID_LBAM; |
| 515 | if (req_task->out_flags.b.hcyl_hob) | 544 | if (req_task->out_flags.b.hcyl_hob) |
| 516 | cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH; | 545 | cmd.valid.out.hob |= IDE_VALID_LBAH; |
| 517 | 546 | ||
| 518 | if (req_task->out_flags.b.error_feature) | 547 | if (req_task->out_flags.b.error_feature) |
| 519 | cmd.tf_flags |= IDE_TFLAG_OUT_FEATURE; | 548 | cmd.valid.out.tf |= IDE_VALID_FEATURE; |
| 520 | if (req_task->out_flags.b.nsector) | 549 | if (req_task->out_flags.b.nsector) |
| 521 | cmd.tf_flags |= IDE_TFLAG_OUT_NSECT; | 550 | cmd.valid.out.tf |= IDE_VALID_NSECT; |
| 522 | if (req_task->out_flags.b.sector) | 551 | if (req_task->out_flags.b.sector) |
| 523 | cmd.tf_flags |= IDE_TFLAG_OUT_LBAL; | 552 | cmd.valid.out.tf |= IDE_VALID_LBAL; |
| 524 | if (req_task->out_flags.b.lcyl) | 553 | if (req_task->out_flags.b.lcyl) |
| 525 | cmd.tf_flags |= IDE_TFLAG_OUT_LBAM; | 554 | cmd.valid.out.tf |= IDE_VALID_LBAM; |
| 526 | if (req_task->out_flags.b.hcyl) | 555 | if (req_task->out_flags.b.hcyl) |
| 527 | cmd.tf_flags |= IDE_TFLAG_OUT_LBAH; | 556 | cmd.valid.out.tf |= IDE_VALID_LBAH; |
| 528 | } else { | 557 | } else { |
| 529 | cmd.tf_flags |= IDE_TFLAG_OUT_TF; | 558 | cmd.valid.out.tf |= IDE_VALID_OUT_TF; |
| 530 | if (cmd.tf_flags & IDE_TFLAG_LBA48) | 559 | if (cmd.tf_flags & IDE_TFLAG_LBA48) |
| 531 | cmd.tf_flags |= IDE_TFLAG_OUT_HOB; | 560 | cmd.valid.out.hob |= IDE_VALID_OUT_HOB; |
| 532 | } | 561 | } |
| 533 | 562 | ||
| 534 | if (req_task->in_flags.b.data) | 563 | if (req_task->in_flags.b.data) |
| @@ -594,7 +623,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) | |||
| 594 | if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA) | 623 | if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA) |
| 595 | nsect = 0; | 624 | nsect = 0; |
| 596 | else if (!nsect) { | 625 | else if (!nsect) { |
| 597 | nsect = (cmd.tf.hob_nsect << 8) | cmd.tf.nsect; | 626 | nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect; |
| 598 | 627 | ||
| 599 | if (!nsect) { | 628 | if (!nsect) { |
| 600 | printk(KERN_ERR "%s: in/out command without data\n", | 629 | printk(KERN_ERR "%s: in/out command without data\n", |
| @@ -606,10 +635,8 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) | |||
| 606 | 635 | ||
| 607 | err = ide_raw_taskfile(drive, &cmd, data_buf, nsect); | 636 | err = ide_raw_taskfile(drive, &cmd, data_buf, nsect); |
| 608 | 637 | ||
| 609 | memcpy(req_task->hob_ports, &cmd.tf_array[0], | 638 | memcpy(req_task->hob_ports, &cmd.hob, HDIO_DRIVE_HOB_HDR_SIZE - 2); |
| 610 | HDIO_DRIVE_HOB_HDR_SIZE - 2); | 639 | memcpy(req_task->io_ports, &cmd.tf, HDIO_DRIVE_TASK_HDR_SIZE); |
| 611 | memcpy(req_task->io_ports, &cmd.tf_array[6], | ||
| 612 | HDIO_DRIVE_TASK_HDR_SIZE); | ||
| 613 | 640 | ||
| 614 | if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) && | 641 | if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) && |
| 615 | req_task->in_flags.all == 0) { | 642 | req_task->in_flags.all == 0) { |
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c index 71a39fb3856f..95327a2c2422 100644 --- a/drivers/ide/ns87415.c +++ b/drivers/ide/ns87415.c | |||
| @@ -61,41 +61,23 @@ static u8 superio_dma_sff_read_status(ide_hwif_t *hwif) | |||
| 61 | return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS); | 61 | return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) | 64 | static void superio_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, |
| 65 | u8 valid) | ||
| 65 | { | 66 | { |
| 66 | struct ide_io_ports *io_ports = &drive->hwif->io_ports; | 67 | struct ide_io_ports *io_ports = &drive->hwif->io_ports; |
| 67 | struct ide_taskfile *tf = &cmd->tf; | ||
| 68 | 68 | ||
| 69 | /* be sure we're looking at the low order bits */ | 69 | if (valid & IDE_VALID_ERROR) |
| 70 | outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 71 | |||
| 72 | if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) | ||
| 73 | tf->error = inb(io_ports->feature_addr); | 70 | tf->error = inb(io_ports->feature_addr); |
| 74 | if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) | 71 | if (valid & IDE_VALID_NSECT) |
| 75 | tf->nsect = inb(io_ports->nsect_addr); | 72 | tf->nsect = inb(io_ports->nsect_addr); |
| 76 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) | 73 | if (valid & IDE_VALID_LBAL) |
| 77 | tf->lbal = inb(io_ports->lbal_addr); | 74 | tf->lbal = inb(io_ports->lbal_addr); |
| 78 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) | 75 | if (valid & IDE_VALID_LBAM) |
| 79 | tf->lbam = inb(io_ports->lbam_addr); | 76 | tf->lbam = inb(io_ports->lbam_addr); |
| 80 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) | 77 | if (valid & IDE_VALID_LBAH) |
| 81 | tf->lbah = inb(io_ports->lbah_addr); | 78 | tf->lbah = inb(io_ports->lbah_addr); |
| 82 | if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) | 79 | if (valid & IDE_VALID_DEVICE) |
| 83 | tf->device = superio_ide_inb(io_ports->device_addr); | 80 | tf->device = superio_ide_inb(io_ports->device_addr); |
| 84 | |||
| 85 | if (cmd->tf_flags & IDE_TFLAG_LBA48) { | ||
| 86 | outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 87 | |||
| 88 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) | ||
| 89 | tf->hob_error = inb(io_ports->feature_addr); | ||
| 90 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
| 91 | tf->hob_nsect = inb(io_ports->nsect_addr); | ||
| 92 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
| 93 | tf->hob_lbal = inb(io_ports->lbal_addr); | ||
| 94 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
| 95 | tf->hob_lbam = inb(io_ports->lbam_addr); | ||
| 96 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
| 97 | tf->hob_lbah = inb(io_ports->lbah_addr); | ||
| 98 | } | ||
| 99 | } | 81 | } |
| 100 | 82 | ||
| 101 | static void ns87415_dev_select(ide_drive_t *drive); | 83 | static void ns87415_dev_select(ide_drive_t *drive); |
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c index d007e7f66598..c79346679244 100644 --- a/drivers/ide/q40ide.c +++ b/drivers/ide/q40ide.c | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #include <linux/blkdev.h> | 16 | #include <linux/blkdev.h> |
| 17 | #include <linux/ide.h> | 17 | #include <linux/ide.h> |
| 18 | 18 | ||
| 19 | #include <asm/ide.h> | ||
| 20 | |||
| 19 | /* | 21 | /* |
| 20 | * Bases of the IDE interfaces | 22 | * Bases of the IDE interfaces |
| 21 | */ | 23 | */ |
| @@ -77,8 +79,10 @@ static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, | |||
| 77 | { | 79 | { |
| 78 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | 80 | unsigned long data_addr = drive->hwif->io_ports.data_addr; |
| 79 | 81 | ||
| 80 | if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) | 82 | if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) { |
| 81 | return insw(data_addr, buf, (len + 1) / 2); | 83 | __ide_mm_insw(data_addr, buf, (len + 1) / 2); |
| 84 | return; | ||
| 85 | } | ||
| 82 | 86 | ||
| 83 | raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2); | 87 | raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2); |
| 84 | } | 88 | } |
| @@ -88,8 +92,10 @@ static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, | |||
| 88 | { | 92 | { |
| 89 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | 93 | unsigned long data_addr = drive->hwif->io_ports.data_addr; |
| 90 | 94 | ||
| 91 | if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) | 95 | if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS)) { |
| 92 | return outsw(data_addr, buf, (len + 1) / 2); | 96 | __ide_mm_outsw(data_addr, buf, (len + 1) / 2); |
| 97 | return; | ||
| 98 | } | ||
| 93 | 99 | ||
| 94 | raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2); | 100 | raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2); |
| 95 | } | 101 | } |
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c index 6d8dbd9c10bc..5be41f25204f 100644 --- a/drivers/ide/scc_pata.c +++ b/drivers/ide/scc_pata.c | |||
| @@ -337,7 +337,6 @@ static void scc_dma_start(ide_drive_t *drive) | |||
| 337 | 337 | ||
| 338 | /* start DMA */ | 338 | /* start DMA */ |
| 339 | scc_ide_outb(dma_cmd | 1, hwif->dma_base); | 339 | scc_ide_outb(dma_cmd | 1, hwif->dma_base); |
| 340 | wmb(); | ||
| 341 | } | 340 | } |
| 342 | 341 | ||
| 343 | static int __scc_dma_end(ide_drive_t *drive) | 342 | static int __scc_dma_end(ide_drive_t *drive) |
| @@ -354,7 +353,6 @@ static int __scc_dma_end(ide_drive_t *drive) | |||
| 354 | /* clear the INTR & ERROR bits */ | 353 | /* clear the INTR & ERROR bits */ |
| 355 | scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); | 354 | scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); |
| 356 | /* verify good DMA status */ | 355 | /* verify good DMA status */ |
| 357 | wmb(); | ||
| 358 | return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; | 356 | return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; |
| 359 | } | 357 | } |
| 360 | 358 | ||
| @@ -647,77 +645,40 @@ static int __devinit init_setup_scc(struct pci_dev *dev, | |||
| 647 | return rc; | 645 | return rc; |
| 648 | } | 646 | } |
| 649 | 647 | ||
| 650 | static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) | 648 | static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) |
| 651 | { | 649 | { |
| 652 | struct ide_io_ports *io_ports = &drive->hwif->io_ports; | 650 | struct ide_io_ports *io_ports = &drive->hwif->io_ports; |
| 653 | struct ide_taskfile *tf = &cmd->tf; | 651 | |
| 654 | u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | 652 | if (valid & IDE_VALID_FEATURE) |
| 655 | |||
| 656 | if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) | ||
| 657 | HIHI = 0xFF; | ||
| 658 | |||
| 659 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
| 660 | scc_ide_outb(tf->hob_feature, io_ports->feature_addr); | ||
| 661 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
| 662 | scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr); | ||
| 663 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
| 664 | scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr); | ||
| 665 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
| 666 | scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr); | ||
| 667 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
| 668 | scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr); | ||
| 669 | |||
| 670 | if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
| 671 | scc_ide_outb(tf->feature, io_ports->feature_addr); | 653 | scc_ide_outb(tf->feature, io_ports->feature_addr); |
| 672 | if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) | 654 | if (valid & IDE_VALID_NSECT) |
| 673 | scc_ide_outb(tf->nsect, io_ports->nsect_addr); | 655 | scc_ide_outb(tf->nsect, io_ports->nsect_addr); |
| 674 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) | 656 | if (valid & IDE_VALID_LBAL) |
| 675 | scc_ide_outb(tf->lbal, io_ports->lbal_addr); | 657 | scc_ide_outb(tf->lbal, io_ports->lbal_addr); |
| 676 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) | 658 | if (valid & IDE_VALID_LBAM) |
| 677 | scc_ide_outb(tf->lbam, io_ports->lbam_addr); | 659 | scc_ide_outb(tf->lbam, io_ports->lbam_addr); |
| 678 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) | 660 | if (valid & IDE_VALID_LBAH) |
| 679 | scc_ide_outb(tf->lbah, io_ports->lbah_addr); | 661 | scc_ide_outb(tf->lbah, io_ports->lbah_addr); |
| 680 | 662 | if (valid & IDE_VALID_DEVICE) | |
| 681 | if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) | 663 | scc_ide_outb(tf->device, io_ports->device_addr); |
| 682 | scc_ide_outb((tf->device & HIHI) | drive->select, | ||
| 683 | io_ports->device_addr); | ||
| 684 | } | 664 | } |
| 685 | 665 | ||
| 686 | static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) | 666 | static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) |
| 687 | { | 667 | { |
| 688 | struct ide_io_ports *io_ports = &drive->hwif->io_ports; | 668 | struct ide_io_ports *io_ports = &drive->hwif->io_ports; |
| 689 | struct ide_taskfile *tf = &cmd->tf; | ||
| 690 | |||
| 691 | /* be sure we're looking at the low order bits */ | ||
| 692 | scc_ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 693 | 669 | ||
| 694 | if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) | 670 | if (valid & IDE_VALID_ERROR) |
| 695 | tf->error = scc_ide_inb(io_ports->feature_addr); | 671 | tf->error = scc_ide_inb(io_ports->feature_addr); |
| 696 | if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) | 672 | if (valid & IDE_VALID_NSECT) |
| 697 | tf->nsect = scc_ide_inb(io_ports->nsect_addr); | 673 | tf->nsect = scc_ide_inb(io_ports->nsect_addr); |
| 698 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) | 674 | if (valid & IDE_VALID_LBAL) |
| 699 | tf->lbal = scc_ide_inb(io_ports->lbal_addr); | 675 | tf->lbal = scc_ide_inb(io_ports->lbal_addr); |
| 700 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) | 676 | if (valid & IDE_VALID_LBAM) |
| 701 | tf->lbam = scc_ide_inb(io_ports->lbam_addr); | 677 | tf->lbam = scc_ide_inb(io_ports->lbam_addr); |
| 702 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) | 678 | if (valid & IDE_VALID_LBAH) |
| 703 | tf->lbah = scc_ide_inb(io_ports->lbah_addr); | 679 | tf->lbah = scc_ide_inb(io_ports->lbah_addr); |
| 704 | if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) | 680 | if (valid & IDE_VALID_DEVICE) |
| 705 | tf->device = scc_ide_inb(io_ports->device_addr); | 681 | tf->device = scc_ide_inb(io_ports->device_addr); |
| 706 | |||
| 707 | if (cmd->tf_flags & IDE_TFLAG_LBA48) { | ||
| 708 | scc_ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 709 | |||
| 710 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) | ||
| 711 | tf->hob_error = scc_ide_inb(io_ports->feature_addr); | ||
| 712 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
| 713 | tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr); | ||
| 714 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
| 715 | tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr); | ||
| 716 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
| 717 | tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr); | ||
| 718 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
| 719 | tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr); | ||
| 720 | } | ||
| 721 | } | 682 | } |
| 722 | 683 | ||
| 723 | static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd, | 684 | static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd, |
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c index 4cb79c4c2604..e33d764e2945 100644 --- a/drivers/ide/tx4938ide.c +++ b/drivers/ide/tx4938ide.c | |||
| @@ -72,91 +72,6 @@ static void tx4938ide_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 72 | #ifdef __BIG_ENDIAN | 72 | #ifdef __BIG_ENDIAN |
| 73 | 73 | ||
| 74 | /* custom iops (independent from SWAP_IO_SPACE) */ | 74 | /* custom iops (independent from SWAP_IO_SPACE) */ |
| 75 | static u8 tx4938ide_inb(unsigned long port) | ||
| 76 | { | ||
| 77 | return __raw_readb((void __iomem *)port); | ||
| 78 | } | ||
| 79 | |||
| 80 | static void tx4938ide_outb(u8 value, unsigned long port) | ||
| 81 | { | ||
| 82 | __raw_writeb(value, (void __iomem *)port); | ||
| 83 | } | ||
| 84 | |||
| 85 | static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) | ||
| 86 | { | ||
| 87 | ide_hwif_t *hwif = drive->hwif; | ||
| 88 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
| 89 | struct ide_taskfile *tf = &cmd->tf; | ||
| 90 | u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; | ||
| 91 | |||
| 92 | if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) | ||
| 93 | HIHI = 0xFF; | ||
| 94 | |||
| 95 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
| 96 | tx4938ide_outb(tf->hob_feature, io_ports->feature_addr); | ||
| 97 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
| 98 | tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr); | ||
| 99 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
| 100 | tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr); | ||
| 101 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
| 102 | tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr); | ||
| 103 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
| 104 | tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr); | ||
| 105 | |||
| 106 | if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
| 107 | tx4938ide_outb(tf->feature, io_ports->feature_addr); | ||
| 108 | if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) | ||
| 109 | tx4938ide_outb(tf->nsect, io_ports->nsect_addr); | ||
| 110 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) | ||
| 111 | tx4938ide_outb(tf->lbal, io_ports->lbal_addr); | ||
| 112 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) | ||
| 113 | tx4938ide_outb(tf->lbam, io_ports->lbam_addr); | ||
| 114 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) | ||
| 115 | tx4938ide_outb(tf->lbah, io_ports->lbah_addr); | ||
| 116 | |||
| 117 | if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) | ||
| 118 | tx4938ide_outb((tf->device & HIHI) | drive->select, | ||
| 119 | io_ports->device_addr); | ||
| 120 | } | ||
| 121 | |||
| 122 | static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) | ||
| 123 | { | ||
| 124 | ide_hwif_t *hwif = drive->hwif; | ||
| 125 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
| 126 | struct ide_taskfile *tf = &cmd->tf; | ||
| 127 | |||
| 128 | /* be sure we're looking at the low order bits */ | ||
| 129 | tx4938ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 130 | |||
| 131 | if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) | ||
| 132 | tf->error = tx4938ide_inb(io_ports->feature_addr); | ||
| 133 | if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) | ||
| 134 | tf->nsect = tx4938ide_inb(io_ports->nsect_addr); | ||
| 135 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) | ||
| 136 | tf->lbal = tx4938ide_inb(io_ports->lbal_addr); | ||
| 137 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) | ||
| 138 | tf->lbam = tx4938ide_inb(io_ports->lbam_addr); | ||
| 139 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) | ||
| 140 | tf->lbah = tx4938ide_inb(io_ports->lbah_addr); | ||
| 141 | if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
| 142 | tf->device = tx4938ide_inb(io_ports->device_addr); | ||
| 143 | |||
| 144 | if (cmd->tf_flags & IDE_TFLAG_LBA48) { | ||
| 145 | tx4938ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 146 | |||
| 147 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) | ||
| 148 | tf->hob_error = tx4938ide_inb(io_ports->feature_addr); | ||
| 149 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
| 150 | tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr); | ||
| 151 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
| 152 | tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr); | ||
| 153 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
| 154 | tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr); | ||
| 155 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
| 156 | tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr); | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, | 75 | static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, |
| 161 | void *buf, unsigned int len) | 76 | void *buf, unsigned int len) |
| 162 | { | 77 | { |
| @@ -190,8 +105,8 @@ static const struct ide_tp_ops tx4938ide_tp_ops = { | |||
| 190 | .write_devctl = ide_write_devctl, | 105 | .write_devctl = ide_write_devctl, |
| 191 | 106 | ||
| 192 | .dev_select = ide_dev_select, | 107 | .dev_select = ide_dev_select, |
| 193 | .tf_load = tx4938ide_tf_load, | 108 | .tf_load = ide_tf_load, |
| 194 | .tf_read = tx4938ide_tf_read, | 109 | .tf_read = ide_tf_read, |
| 195 | 110 | ||
| 196 | .input_data = tx4938ide_input_data_swap, | 111 | .input_data = tx4938ide_input_data_swap, |
| 197 | .output_data = tx4938ide_output_data_swap, | 112 | .output_data = tx4938ide_output_data_swap, |
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c index 0040a9a3e26e..564422d23976 100644 --- a/drivers/ide/tx4939ide.c +++ b/drivers/ide/tx4939ide.c | |||
| @@ -327,15 +327,15 @@ static int tx4939ide_dma_end(ide_drive_t *drive) | |||
| 327 | /* read and clear the INTR & ERROR bits */ | 327 | /* read and clear the INTR & ERROR bits */ |
| 328 | dma_stat = tx4939ide_clear_dma_status(base); | 328 | dma_stat = tx4939ide_clear_dma_status(base); |
| 329 | 329 | ||
| 330 | wmb(); | 330 | #define CHECK_DMA_MASK (ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR) |
| 331 | 331 | ||
| 332 | /* verify good DMA status */ | 332 | /* verify good DMA status */ |
| 333 | if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 && | 333 | if ((dma_stat & CHECK_DMA_MASK) == 0 && |
| 334 | (ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) == | 334 | (ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) == |
| 335 | (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) | 335 | (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) |
| 336 | /* INT_IDE lost... bug? */ | 336 | /* INT_IDE lost... bug? */ |
| 337 | return 0; | 337 | return 0; |
| 338 | return ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) != | 338 | return ((dma_stat & CHECK_DMA_MASK) != |
| 339 | ATA_DMA_INTR) ? 0x10 | dma_stat : 0; | 339 | ATA_DMA_INTR) ? 0x10 | dma_stat : 0; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| @@ -434,97 +434,19 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive) | |||
| 434 | tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl); | 434 | tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl); |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | #ifdef __BIG_ENDIAN | 437 | static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, |
| 438 | 438 | u8 valid) | |
| 439 | /* custom iops (independent from SWAP_IO_SPACE) */ | ||
| 440 | static u8 tx4939ide_inb(unsigned long port) | ||
| 441 | { | 439 | { |
| 442 | return __raw_readb((void __iomem *)port); | 440 | ide_tf_load(drive, tf, valid); |
| 443 | } | ||
| 444 | 441 | ||
| 445 | static void tx4939ide_outb(u8 value, unsigned long port) | 442 | if (valid & IDE_VALID_DEVICE) |
| 446 | { | ||
| 447 | __raw_writeb(value, (void __iomem *)port); | ||
| 448 | } | ||
| 449 | |||
| 450 | static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) | ||
| 451 | { | ||
| 452 | ide_hwif_t *hwif = drive->hwif; | ||
| 453 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
| 454 | struct ide_taskfile *tf = &cmd->tf; | ||
| 455 | u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF; | ||
| 456 | |||
| 457 | if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) | ||
| 458 | HIHI = 0xFF; | ||
| 459 | |||
| 460 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
| 461 | tx4939ide_outb(tf->hob_feature, io_ports->feature_addr); | ||
| 462 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
| 463 | tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr); | ||
| 464 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
| 465 | tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr); | ||
| 466 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
| 467 | tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr); | ||
| 468 | if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
| 469 | tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr); | ||
| 470 | |||
| 471 | if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
| 472 | tx4939ide_outb(tf->feature, io_ports->feature_addr); | ||
| 473 | if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) | ||
| 474 | tx4939ide_outb(tf->nsect, io_ports->nsect_addr); | ||
| 475 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) | ||
| 476 | tx4939ide_outb(tf->lbal, io_ports->lbal_addr); | ||
| 477 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) | ||
| 478 | tx4939ide_outb(tf->lbam, io_ports->lbam_addr); | ||
| 479 | if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) | ||
| 480 | tx4939ide_outb(tf->lbah, io_ports->lbah_addr); | ||
| 481 | |||
| 482 | if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) { | ||
| 483 | tx4939ide_outb((tf->device & HIHI) | drive->select, | ||
| 484 | io_ports->device_addr); | ||
| 485 | tx4939ide_tf_load_fixup(drive); | 443 | tx4939ide_tf_load_fixup(drive); |
| 486 | } | ||
| 487 | } | 444 | } |
| 488 | 445 | ||
| 489 | static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) | 446 | #ifdef __BIG_ENDIAN |
| 490 | { | ||
| 491 | ide_hwif_t *hwif = drive->hwif; | ||
| 492 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
| 493 | struct ide_taskfile *tf = &cmd->tf; | ||
| 494 | |||
| 495 | /* be sure we're looking at the low order bits */ | ||
| 496 | tx4939ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 497 | |||
| 498 | if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) | ||
| 499 | tf->error = tx4939ide_inb(io_ports->feature_addr); | ||
| 500 | if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) | ||
| 501 | tf->nsect = tx4939ide_inb(io_ports->nsect_addr); | ||
| 502 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) | ||
| 503 | tf->lbal = tx4939ide_inb(io_ports->lbal_addr); | ||
| 504 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) | ||
| 505 | tf->lbam = tx4939ide_inb(io_ports->lbam_addr); | ||
| 506 | if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) | ||
| 507 | tf->lbah = tx4939ide_inb(io_ports->lbah_addr); | ||
| 508 | if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
| 509 | tf->device = tx4939ide_inb(io_ports->device_addr); | ||
| 510 | |||
| 511 | if (cmd->tf_flags & IDE_TFLAG_LBA48) { | ||
| 512 | tx4939ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); | ||
| 513 | |||
| 514 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) | ||
| 515 | tf->hob_error = tx4939ide_inb(io_ports->feature_addr); | ||
| 516 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
| 517 | tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr); | ||
| 518 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
| 519 | tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr); | ||
| 520 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
| 521 | tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr); | ||
| 522 | if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
| 523 | tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr); | ||
| 524 | } | ||
| 525 | } | ||
| 526 | 447 | ||
| 527 | static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq, | 448 | /* custom iops (independent from SWAP_IO_SPACE) */ |
| 449 | static void tx4939ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, | ||
| 528 | void *buf, unsigned int len) | 450 | void *buf, unsigned int len) |
| 529 | { | 451 | { |
| 530 | unsigned long port = drive->hwif->io_ports.data_addr; | 452 | unsigned long port = drive->hwif->io_ports.data_addr; |
| @@ -536,7 +458,7 @@ static void tx4939ide_input_data_swap(ide_drive_t *drive, struct request *rq, | |||
| 536 | __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); | 458 | __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); |
| 537 | } | 459 | } |
| 538 | 460 | ||
| 539 | static void tx4939ide_output_data_swap(ide_drive_t *drive, struct request *rq, | 461 | static void tx4939ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd, |
| 540 | void *buf, unsigned int len) | 462 | void *buf, unsigned int len) |
| 541 | { | 463 | { |
| 542 | unsigned long port = drive->hwif->io_ports.data_addr; | 464 | unsigned long port = drive->hwif->io_ports.data_addr; |
| @@ -558,7 +480,7 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { | |||
| 558 | 480 | ||
| 559 | .dev_select = ide_dev_select, | 481 | .dev_select = ide_dev_select, |
| 560 | .tf_load = tx4939ide_tf_load, | 482 | .tf_load = tx4939ide_tf_load, |
| 561 | .tf_read = tx4939ide_tf_read, | 483 | .tf_read = ide_tf_read, |
| 562 | 484 | ||
| 563 | .input_data = tx4939ide_input_data_swap, | 485 | .input_data = tx4939ide_input_data_swap, |
| 564 | .output_data = tx4939ide_output_data_swap, | 486 | .output_data = tx4939ide_output_data_swap, |
| @@ -566,14 +488,6 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { | |||
| 566 | 488 | ||
| 567 | #else /* __LITTLE_ENDIAN */ | 489 | #else /* __LITTLE_ENDIAN */ |
| 568 | 490 | ||
| 569 | static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) | ||
| 570 | { | ||
| 571 | ide_tf_load(drive, cmd); | ||
| 572 | |||
| 573 | if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) | ||
| 574 | tx4939ide_tf_load_fixup(drive); | ||
| 575 | } | ||
| 576 | |||
| 577 | static const struct ide_tp_ops tx4939ide_tp_ops = { | 491 | static const struct ide_tp_ops tx4939ide_tp_ops = { |
| 578 | .exec_command = ide_exec_command, | 492 | .exec_command = ide_exec_command, |
| 579 | .read_status = ide_read_status, | 493 | .read_status = ide_read_status, |
diff --git a/include/linux/ide.h b/include/linux/ide.h index a5d26f66ef78..ff65fffb078f 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -240,65 +240,38 @@ typedef enum { | |||
| 240 | } ide_startstop_t; | 240 | } ide_startstop_t; |
| 241 | 241 | ||
| 242 | enum { | 242 | enum { |
| 243 | IDE_VALID_ERROR = (1 << 1), | ||
| 244 | IDE_VALID_FEATURE = IDE_VALID_ERROR, | ||
| 245 | IDE_VALID_NSECT = (1 << 2), | ||
| 246 | IDE_VALID_LBAL = (1 << 3), | ||
| 247 | IDE_VALID_LBAM = (1 << 4), | ||
| 248 | IDE_VALID_LBAH = (1 << 5), | ||
| 249 | IDE_VALID_DEVICE = (1 << 6), | ||
| 250 | IDE_VALID_LBA = IDE_VALID_LBAL | | ||
| 251 | IDE_VALID_LBAM | | ||
| 252 | IDE_VALID_LBAH, | ||
| 253 | IDE_VALID_OUT_TF = IDE_VALID_FEATURE | | ||
| 254 | IDE_VALID_NSECT | | ||
| 255 | IDE_VALID_LBA, | ||
| 256 | IDE_VALID_IN_TF = IDE_VALID_NSECT | | ||
| 257 | IDE_VALID_LBA, | ||
| 258 | IDE_VALID_OUT_HOB = IDE_VALID_OUT_TF, | ||
| 259 | IDE_VALID_IN_HOB = IDE_VALID_ERROR | | ||
| 260 | IDE_VALID_NSECT | | ||
| 261 | IDE_VALID_LBA, | ||
| 262 | }; | ||
| 263 | |||
| 264 | enum { | ||
| 243 | IDE_TFLAG_LBA48 = (1 << 0), | 265 | IDE_TFLAG_LBA48 = (1 << 0), |
| 244 | IDE_TFLAG_OUT_HOB_FEATURE = (1 << 1), | 266 | IDE_TFLAG_WRITE = (1 << 1), |
| 245 | IDE_TFLAG_OUT_HOB_NSECT = (1 << 2), | 267 | IDE_TFLAG_CUSTOM_HANDLER = (1 << 2), |
| 246 | IDE_TFLAG_OUT_HOB_LBAL = (1 << 3), | 268 | IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 3), |
| 247 | IDE_TFLAG_OUT_HOB_LBAM = (1 << 4), | ||
| 248 | IDE_TFLAG_OUT_HOB_LBAH = (1 << 5), | ||
| 249 | IDE_TFLAG_OUT_HOB = IDE_TFLAG_OUT_HOB_FEATURE | | ||
| 250 | IDE_TFLAG_OUT_HOB_NSECT | | ||
| 251 | IDE_TFLAG_OUT_HOB_LBAL | | ||
| 252 | IDE_TFLAG_OUT_HOB_LBAM | | ||
| 253 | IDE_TFLAG_OUT_HOB_LBAH, | ||
| 254 | IDE_TFLAG_OUT_FEATURE = (1 << 6), | ||
| 255 | IDE_TFLAG_OUT_NSECT = (1 << 7), | ||
| 256 | IDE_TFLAG_OUT_LBAL = (1 << 8), | ||
| 257 | IDE_TFLAG_OUT_LBAM = (1 << 9), | ||
| 258 | IDE_TFLAG_OUT_LBAH = (1 << 10), | ||
| 259 | IDE_TFLAG_OUT_TF = IDE_TFLAG_OUT_FEATURE | | ||
| 260 | IDE_TFLAG_OUT_NSECT | | ||
| 261 | IDE_TFLAG_OUT_LBAL | | ||
| 262 | IDE_TFLAG_OUT_LBAM | | ||
| 263 | IDE_TFLAG_OUT_LBAH, | ||
| 264 | IDE_TFLAG_OUT_DEVICE = (1 << 11), | ||
| 265 | IDE_TFLAG_WRITE = (1 << 12), | ||
| 266 | IDE_TFLAG_CUSTOM_HANDLER = (1 << 13), | ||
| 267 | IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 14), | ||
| 268 | IDE_TFLAG_IN_HOB_ERROR = (1 << 15), | ||
| 269 | IDE_TFLAG_IN_HOB_NSECT = (1 << 16), | ||
| 270 | IDE_TFLAG_IN_HOB_LBAL = (1 << 17), | ||
| 271 | IDE_TFLAG_IN_HOB_LBAM = (1 << 18), | ||
| 272 | IDE_TFLAG_IN_HOB_LBAH = (1 << 19), | ||
| 273 | IDE_TFLAG_IN_HOB_LBA = IDE_TFLAG_IN_HOB_LBAL | | ||
| 274 | IDE_TFLAG_IN_HOB_LBAM | | ||
| 275 | IDE_TFLAG_IN_HOB_LBAH, | ||
| 276 | IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_ERROR | | ||
| 277 | IDE_TFLAG_IN_HOB_NSECT | | ||
| 278 | IDE_TFLAG_IN_HOB_LBA, | ||
| 279 | IDE_TFLAG_IN_ERROR = (1 << 20), | ||
| 280 | IDE_TFLAG_IN_NSECT = (1 << 21), | ||
| 281 | IDE_TFLAG_IN_LBAL = (1 << 22), | ||
| 282 | IDE_TFLAG_IN_LBAM = (1 << 23), | ||
| 283 | IDE_TFLAG_IN_LBAH = (1 << 24), | ||
| 284 | IDE_TFLAG_IN_LBA = IDE_TFLAG_IN_LBAL | | ||
| 285 | IDE_TFLAG_IN_LBAM | | ||
| 286 | IDE_TFLAG_IN_LBAH, | ||
| 287 | IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | | ||
| 288 | IDE_TFLAG_IN_LBA, | ||
| 289 | IDE_TFLAG_IN_DEVICE = (1 << 25), | ||
| 290 | IDE_TFLAG_HOB = IDE_TFLAG_OUT_HOB | | ||
| 291 | IDE_TFLAG_IN_HOB, | ||
| 292 | IDE_TFLAG_TF = IDE_TFLAG_OUT_TF | | ||
| 293 | IDE_TFLAG_IN_TF, | ||
| 294 | IDE_TFLAG_DEVICE = IDE_TFLAG_OUT_DEVICE | | ||
| 295 | IDE_TFLAG_IN_DEVICE, | ||
| 296 | /* force 16-bit I/O operations */ | 269 | /* force 16-bit I/O operations */ |
| 297 | IDE_TFLAG_IO_16BIT = (1 << 26), | 270 | IDE_TFLAG_IO_16BIT = (1 << 4), |
| 298 | /* struct ide_cmd was allocated using kmalloc() */ | 271 | /* struct ide_cmd was allocated using kmalloc() */ |
| 299 | IDE_TFLAG_DYN = (1 << 27), | 272 | IDE_TFLAG_DYN = (1 << 5), |
| 300 | IDE_TFLAG_FS = (1 << 28), | 273 | IDE_TFLAG_FS = (1 << 6), |
| 301 | IDE_TFLAG_MULTI_PIO = (1 << 29), | 274 | IDE_TFLAG_MULTI_PIO = (1 << 7), |
| 302 | }; | 275 | }; |
| 303 | 276 | ||
| 304 | enum { | 277 | enum { |
| @@ -309,45 +282,34 @@ enum { | |||
| 309 | }; | 282 | }; |
| 310 | 283 | ||
| 311 | struct ide_taskfile { | 284 | struct ide_taskfile { |
| 312 | u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */ | 285 | u8 data; /* 0: data byte (for TASKFILE ioctl) */ |
| 313 | /* 1-5: additional data to support LBA48 */ | 286 | union { /* 1: */ |
| 314 | union { | 287 | u8 error; /* read: error */ |
| 315 | u8 hob_error; /* read: error */ | 288 | u8 feature; /* write: feature */ |
| 316 | u8 hob_feature; /* write: feature */ | ||
| 317 | }; | ||
| 318 | |||
| 319 | u8 hob_nsect; | ||
| 320 | u8 hob_lbal; | ||
| 321 | u8 hob_lbam; | ||
| 322 | u8 hob_lbah; | ||
| 323 | |||
| 324 | u8 data; /* 6: low data byte (for TASKFILE IOCTL) */ | ||
| 325 | |||
| 326 | union { /* 7: */ | ||
| 327 | u8 error; /* read: error */ | ||
| 328 | u8 feature; /* write: feature */ | ||
| 329 | }; | 289 | }; |
| 330 | 290 | u8 nsect; /* 2: number of sectors */ | |
| 331 | u8 nsect; /* 8: number of sectors */ | 291 | u8 lbal; /* 3: LBA low */ |
| 332 | u8 lbal; /* 9: LBA low */ | 292 | u8 lbam; /* 4: LBA mid */ |
| 333 | u8 lbam; /* 10: LBA mid */ | 293 | u8 lbah; /* 5: LBA high */ |
| 334 | u8 lbah; /* 11: LBA high */ | 294 | u8 device; /* 6: device select */ |
| 335 | 295 | union { /* 7: */ | |
| 336 | u8 device; /* 12: device select */ | 296 | u8 status; /* read: status */ |
| 337 | |||
| 338 | union { /* 13: */ | ||
| 339 | u8 status; /* read: status */ | ||
| 340 | u8 command; /* write: command */ | 297 | u8 command; /* write: command */ |
| 341 | }; | 298 | }; |
| 342 | }; | 299 | }; |
| 343 | 300 | ||
| 344 | struct ide_cmd { | 301 | struct ide_cmd { |
| 345 | union { | 302 | struct ide_taskfile tf; |
| 346 | struct ide_taskfile tf; | 303 | struct ide_taskfile hob; |
| 347 | u8 tf_array[14]; | 304 | struct { |
| 348 | }; | 305 | struct { |
| 306 | u8 tf; | ||
| 307 | u8 hob; | ||
| 308 | } out, in; | ||
| 309 | } valid; | ||
| 310 | |||
| 311 | u8 tf_flags; | ||
| 349 | u8 ftf_flags; /* for TASKFILE ioctl */ | 312 | u8 ftf_flags; /* for TASKFILE ioctl */ |
| 350 | u32 tf_flags; | ||
| 351 | int protocol; | 313 | int protocol; |
| 352 | 314 | ||
| 353 | int sg_nents; /* number of sg entries */ | 315 | int sg_nents; /* number of sg entries */ |
| @@ -662,8 +624,8 @@ struct ide_tp_ops { | |||
| 662 | void (*write_devctl)(struct hwif_s *, u8); | 624 | void (*write_devctl)(struct hwif_s *, u8); |
| 663 | 625 | ||
| 664 | void (*dev_select)(ide_drive_t *); | 626 | void (*dev_select)(ide_drive_t *); |
| 665 | void (*tf_load)(ide_drive_t *, struct ide_cmd *); | 627 | void (*tf_load)(ide_drive_t *, struct ide_taskfile *, u8); |
| 666 | void (*tf_read)(ide_drive_t *, struct ide_cmd *); | 628 | void (*tf_read)(ide_drive_t *, struct ide_taskfile *, u8); |
| 667 | 629 | ||
| 668 | void (*input_data)(ide_drive_t *, struct ide_cmd *, | 630 | void (*input_data)(ide_drive_t *, struct ide_cmd *, |
| 669 | void *, unsigned int); | 631 | void *, unsigned int); |
| @@ -1162,7 +1124,8 @@ extern int ide_devset_execute(ide_drive_t *drive, | |||
| 1162 | void ide_complete_cmd(ide_drive_t *, struct ide_cmd *, u8, u8); | 1124 | void ide_complete_cmd(ide_drive_t *, struct ide_cmd *, u8, u8); |
| 1163 | int ide_complete_rq(ide_drive_t *, int, unsigned int); | 1125 | int ide_complete_rq(ide_drive_t *, int, unsigned int); |
| 1164 | 1126 | ||
| 1165 | void ide_tf_dump(const char *, struct ide_taskfile *); | 1127 | void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd); |
| 1128 | void ide_tf_dump(const char *, struct ide_cmd *); | ||
| 1166 | 1129 | ||
| 1167 | void ide_exec_command(ide_hwif_t *, u8); | 1130 | void ide_exec_command(ide_hwif_t *, u8); |
| 1168 | u8 ide_read_status(ide_hwif_t *); | 1131 | u8 ide_read_status(ide_hwif_t *); |
| @@ -1170,8 +1133,8 @@ u8 ide_read_altstatus(ide_hwif_t *); | |||
| 1170 | void ide_write_devctl(ide_hwif_t *, u8); | 1133 | void ide_write_devctl(ide_hwif_t *, u8); |
| 1171 | 1134 | ||
| 1172 | void ide_dev_select(ide_drive_t *); | 1135 | void ide_dev_select(ide_drive_t *); |
| 1173 | void ide_tf_load(ide_drive_t *, struct ide_cmd *); | 1136 | void ide_tf_load(ide_drive_t *, struct ide_taskfile *, u8); |
| 1174 | void ide_tf_read(ide_drive_t *, struct ide_cmd *); | 1137 | void ide_tf_read(ide_drive_t *, struct ide_taskfile *, u8); |
| 1175 | 1138 | ||
| 1176 | void ide_input_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int); | 1139 | void ide_input_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int); |
| 1177 | void ide_output_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int); | 1140 | void ide_output_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int); |
| @@ -1529,7 +1492,7 @@ static inline void ide_set_hwifdata (ide_hwif_t * hwif, void *data) | |||
| 1529 | 1492 | ||
| 1530 | extern void ide_toggle_bounce(ide_drive_t *drive, int on); | 1493 | extern void ide_toggle_bounce(ide_drive_t *drive, int on); |
| 1531 | 1494 | ||
| 1532 | u64 ide_get_lba_addr(struct ide_taskfile *, int); | 1495 | u64 ide_get_lba_addr(struct ide_cmd *, int); |
| 1533 | u8 ide_dump_status(ide_drive_t *, const char *, u8); | 1496 | u8 ide_dump_status(ide_drive_t *, const char *, u8); |
| 1534 | 1497 | ||
| 1535 | struct ide_timing { | 1498 | struct ide_timing { |
