diff options
Diffstat (limited to 'drivers/ide/it821x.c')
| -rw-r--r-- | drivers/ide/it821x.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index 0be27ac1f07..f01ba4606be 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c @@ -5,9 +5,8 @@ * May be copied or modified under the terms of the GNU General Public License * Based in part on the ITE vendor provided SCSI driver. * - * Documentation available from - * http://www.ite.com.tw/pc/IT8212F_V04.pdf - * Some other documents are NDA. + * Documentation: + * Datasheet is freely available, some other documents under NDA. * * The ITE8212 isn't exactly a standard IDE controller. It has two * modes. In pass through mode then it is an IDE controller. In its smart @@ -62,12 +61,15 @@ #include <linux/types.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/pci.h> #include <linux/ide.h> #include <linux/init.h> #define DRV_NAME "it821x" +#define QUIRK_VORTEX86 1 + struct it821x_dev { unsigned int smart:1, /* Are we in smart raid mode */ @@ -79,6 +81,7 @@ struct it821x_dev u16 pio[2]; /* Cached PIO values */ u16 mwdma[2]; /* Cached MWDMA values */ u16 udma[2]; /* Cached UDMA values (per drive) */ + u16 quirks; }; #define ATA_66 0 @@ -226,18 +229,18 @@ static void it821x_clock_strategy(ide_drive_t *drive) /** * it821x_set_pio_mode - set host controller for PIO mode + * @hwif: port * @drive: drive - * @pio: PIO mode number * * Tune the host to the desired PIO mode taking into the consideration * the maximum PIO mode supported by the other device on the cable. */ -static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio) +static void it821x_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); ide_drive_t *pair = ide_get_pair_dev(drive); + const u8 pio = drive->pio_mode - XFER_PIO_0; u8 unit = drive->dn & 1, set_pio = pio; /* Spec says 89 ref driver uses 88 */ @@ -250,7 +253,7 @@ static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio) * on the cable. */ if (pair) { - u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4); + u8 pair_pio = pair->pio_mode - XFER_PIO_0; /* trim PIO to the slowest of the master/slave */ if (pair_pio < set_pio) set_pio = pair_pio; @@ -391,14 +394,16 @@ static int it821x_dma_end(ide_drive_t *drive) /** * it821x_set_dma_mode - set host controller for DMA mode + * @hwif: port * @drive: drive - * @speed: DMA mode * * Tune the ITE chipset for the desired DMA mode. */ -static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed) +static void it821x_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) { + const u8 speed = drive->dma_mode; + /* * MWDMA tuning is really hard because our MWDMA and PIO * timings are kept in the same place. We can switch in the @@ -506,12 +511,11 @@ static void it821x_quirkproc(ide_drive_t *drive) static struct ide_dma_ops it821x_pass_through_dma_ops = { .dma_host_set = ide_dma_host_set, .dma_setup = ide_dma_setup, - .dma_exec_cmd = ide_dma_exec_cmd, .dma_start = it821x_dma_start, .dma_end = it821x_dma_end, .dma_test_irq = ide_dma_test_irq, - .dma_timeout = ide_dma_timeout, .dma_lost_irq = ide_dma_lost_irq, + .dma_timer_expiry = ide_dma_sff_timer_expiry, .dma_sff_read_status = ide_dma_sff_read_status, }; @@ -524,7 +528,7 @@ static struct ide_dma_ops it821x_pass_through_dma_ops = { * ide DMA handlers appropriately */ -static void __devinit init_hwif_it821x(ide_hwif_t *hwif) +static void init_hwif_it821x(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); struct ide_host *host = pci_get_drvdata(dev); @@ -557,8 +561,7 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) * this is necessary. */ - pci_read_config_byte(dev, 0x08, &conf); - if (conf == 0x10) { + if (dev->revision == 0x10) { idev->timing10 = 1; hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; if (idev->smart == 0) @@ -577,6 +580,12 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) hwif->ultra_mask = ATA_UDMA6; hwif->mwdma_mask = ATA_MWDMA2; + + /* Vortex86SX quirk: prevent Ultra-DMA mode to fix BadCRC issue */ + if (idev->quirks & QUIRK_VORTEX86) { + if (dev->revision == 0x11) + hwif->ultra_mask = 0; + } } static void it8212_disable_raid(struct pci_dev *dev) @@ -596,7 +605,7 @@ static void it8212_disable_raid(struct pci_dev *dev) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); } -static unsigned int init_chipset_it821x(struct pci_dev *dev) +static int init_chipset_it821x(struct pci_dev *dev) { u8 conf; static char *mode[2] = { "pass through", "smart" }; @@ -621,7 +630,7 @@ static const struct ide_port_ops it821x_port_ops = { .cable_detect = it821x_cable_detect, }; -static const struct ide_port_info it821x_chipset __devinitdata = { +static const struct ide_port_info it821x_chipset = { .name = DRV_NAME, .init_chipset = init_chipset_it821x, .init_hwif = init_hwif_it821x, @@ -638,7 +647,7 @@ static const struct ide_port_info it821x_chipset __devinitdata = { * We then use the IDE PCI generic helper to do most of the work. */ -static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id) +static int it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { struct it821x_dev *itdevs; int rc; @@ -649,6 +658,8 @@ static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_devic return -ENOMEM; } + itdevs->quirks = id->driver_data; + rc = ide_pci_init_one(dev, &it821x_chipset, itdevs); if (rc) kfree(itdevs); @@ -656,7 +667,7 @@ static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_devic return rc; } -static void __devexit it821x_remove(struct pci_dev *dev) +static void it821x_remove(struct pci_dev *dev) { struct ide_host *host = pci_get_drvdata(dev); struct it821x_dev *itdevs = host->host_priv; @@ -668,6 +679,7 @@ static void __devexit it821x_remove(struct pci_dev *dev) static const struct pci_device_id it821x_pci_tbl[] = { { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), 0 }, { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), 0 }, + { PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1010), QUIRK_VORTEX86 }, { 0, }, }; @@ -677,7 +689,7 @@ static struct pci_driver it821x_pci_driver = { .name = "ITE821x IDE", .id_table = it821x_pci_tbl, .probe = it821x_init_one, - .remove = __devexit_p(it821x_remove), + .remove = it821x_remove, .suspend = ide_pci_suspend, .resume = ide_pci_resume, }; |
