diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/via82cxxx.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 11b3e711451a..46e8ddbdf031 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c | |||
@@ -107,6 +107,7 @@ struct via82cxxx_dev | |||
107 | { | 107 | { |
108 | struct via_isa_bridge *via_config; | 108 | struct via_isa_bridge *via_config; |
109 | unsigned int via_80w; | 109 | unsigned int via_80w; |
110 | u8 cached_device[2]; | ||
110 | }; | 111 | }; |
111 | 112 | ||
112 | /** | 113 | /** |
@@ -382,10 +383,66 @@ static const struct ide_port_ops via_port_ops = { | |||
382 | .cable_detect = via82cxxx_cable_detect, | 383 | .cable_detect = via82cxxx_cable_detect, |
383 | }; | 384 | }; |
384 | 385 | ||
386 | static void via_write_devctl(ide_hwif_t *hwif, u8 ctl) | ||
387 | { | ||
388 | struct via82cxxx_dev *vdev = hwif->host->host_priv; | ||
389 | |||
390 | outb(ctl, hwif->io_ports.ctl_addr); | ||
391 | outb(vdev->cached_device[hwif->channel], hwif->io_ports.device_addr); | ||
392 | } | ||
393 | |||
394 | static void __via_dev_select(ide_drive_t *drive, u8 select) | ||
395 | { | ||
396 | ide_hwif_t *hwif = drive->hwif; | ||
397 | struct via82cxxx_dev *vdev = hwif->host->host_priv; | ||
398 | |||
399 | outb(select, hwif->io_ports.device_addr); | ||
400 | vdev->cached_device[hwif->channel] = select; | ||
401 | } | ||
402 | |||
403 | static void via_dev_select(ide_drive_t *drive) | ||
404 | { | ||
405 | __via_dev_select(drive, drive->select | ATA_DEVICE_OBS); | ||
406 | } | ||
407 | |||
408 | static void via_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) | ||
409 | { | ||
410 | ide_hwif_t *hwif = drive->hwif; | ||
411 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
412 | |||
413 | if (valid & IDE_VALID_FEATURE) | ||
414 | outb(tf->feature, io_ports->feature_addr); | ||
415 | if (valid & IDE_VALID_NSECT) | ||
416 | outb(tf->nsect, io_ports->nsect_addr); | ||
417 | if (valid & IDE_VALID_LBAL) | ||
418 | outb(tf->lbal, io_ports->lbal_addr); | ||
419 | if (valid & IDE_VALID_LBAM) | ||
420 | outb(tf->lbam, io_ports->lbam_addr); | ||
421 | if (valid & IDE_VALID_LBAH) | ||
422 | outb(tf->lbah, io_ports->lbah_addr); | ||
423 | if (valid & IDE_VALID_DEVICE) | ||
424 | __via_dev_select(drive, tf->device); | ||
425 | } | ||
426 | |||
427 | const struct ide_tp_ops via_tp_ops = { | ||
428 | .exec_command = ide_exec_command, | ||
429 | .read_status = ide_read_status, | ||
430 | .read_altstatus = ide_read_altstatus, | ||
431 | .write_devctl = via_write_devctl, | ||
432 | |||
433 | .dev_select = via_dev_select, | ||
434 | .tf_load = via_tf_load, | ||
435 | .tf_read = ide_tf_read, | ||
436 | |||
437 | .input_data = ide_input_data, | ||
438 | .output_data = ide_output_data, | ||
439 | }; | ||
440 | |||
385 | static const struct ide_port_info via82cxxx_chipset __devinitdata = { | 441 | static const struct ide_port_info via82cxxx_chipset __devinitdata = { |
386 | .name = DRV_NAME, | 442 | .name = DRV_NAME, |
387 | .init_chipset = init_chipset_via82cxxx, | 443 | .init_chipset = init_chipset_via82cxxx, |
388 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, | 444 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, |
445 | .tp_ops = &via_tp_ops, | ||
389 | .port_ops = &via_port_ops, | 446 | .port_ops = &via_port_ops, |
390 | .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | | 447 | .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | |
391 | IDE_HFLAG_POST_SET_MODE | | 448 | IDE_HFLAG_POST_SET_MODE | |