diff options
Diffstat (limited to 'drivers/ata/pata_hpt3x2n.c')
| -rw-r--r-- | drivers/ata/pata_hpt3x2n.c | 508 |
1 files changed, 270 insertions, 238 deletions
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 06c8db079b9..b93c0f0729e 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -1,5 +1,5 @@ /* - * Libata driver for the highpoint 372N and 302N UDMA66 ATA controllers. + * Libata driver for the HighPoint 371N, 372N, and 302N UDMA66 ATA controllers. * * This driver is heavily based upon: * @@ -8,24 +8,25 @@ * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc + * Portions Copyright (C) 2005-2010 MontaVista Software, Inc. * * * TODO - * 371N * Work out best PLL policy */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> -#include <linux/init.h> #include <linux/blkdev.h> #include <linux/delay.h> #include <scsi/scsi_host.h> #include <linux/libata.h> #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.3.15" enum { HPT_PCI_FAST = (1 << 31), @@ -45,25 +46,24 @@ struct hpt_chip { /* key for bus clock timings * bit - * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW - * DMA. cycles = value + 1 - * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW - * DMA. cycles = value + 1 - * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file + * 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA. + * cycles = value + 1 + * 4:8 data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA. + * cycles = value + 1 + * 9:12 cmd_high_time. Inactive time of DIOW_/DIOR_ during task file * register access. - * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file + * 13:17 cmd_low_time. Active time of DIOW_/DIOR_ during task file * register access. - * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. - * during task file register access. - * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA - * xfer. - * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task + * 18:20 udma_cycle_time. Clock cycles for UDMA xfer. + * 21 CLK frequency for UDMA: 0=ATA clock, 1=dual ATA clock. + * 22:24 pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer. + * 25:27 cmd_pre_high_time. Time to initialize 1st PIO cycle for task file * register access. - * 28 UDMA enable - * 29 DMA enable - * 30 PIO_MST enable. if set, the chip is in bus master mode during - * PIO. - * 31 FIFO enable. + * 28 UDMA enable. + * 29 DMA enable. + * 30 PIO_MST enable. If set, the chip is in bus master mode during + * PIO xfer. + * 31 FIFO enable. Only for PIO. */ /* 66MHz DPLL clocks */ @@ -80,14 +80,13 @@ static struct hpt_clock hpt3x2n_clocks[] = { { XFER_MW_DMA_2, 0x2c829c62 }, { XFER_MW_DMA_1, 0x2c829c66 }, - { XFER_MW_DMA_0, 0x2c829d2c }, + { XFER_MW_DMA_0, 0x2c829d2e }, { XFER_PIO_4, 0x0c829c62 }, { XFER_PIO_3, 0x0c829c84 }, { XFER_PIO_2, 0x0c829ca6 }, { XFER_PIO_1, 0x0d029d26 }, { XFER_PIO_0, 0x0d029d5e }, - { 0, 0x0d029d5e } }; /** @@ -105,7 +104,7 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) { struct hpt_clock *clocks = hpt3x2n_clocks; - while(clocks->xfer_speed) { + while (clocks->xfer_speed) { if (clocks->xfer_speed == speed) return clocks->timing; clocks++; @@ -115,64 +114,76 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) } /** - * hpt3x2n_pre_reset - reset the hpt3x2n bus - * @ap: ATA port to reset + * hpt372n_filter - mode selection filter + * @adev: ATA device + * @mask: mode mask * - * Perform the initial reset handling for the 3x2n series controllers. - * Reset the hardware and state machine, obtain the cable type. + * The Marvell bridge chips used on the HighPoint SATA cards do not seem + * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes... */ +static unsigned long hpt372n_filter(struct ata_device *adev, unsigned long mask) +{ + if (ata_id_is_sata(adev->id)) + mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA); -static int hpt3xn_pre_reset(struct ata_port *ap) + return mask; +} + +/** + * hpt3x2n_cable_detect - Detect the cable type + * @ap: ATA port to detect on + * + * Return the cable type attached to this port + */ + +static int hpt3x2n_cable_detect(struct ata_port *ap) { u8 scr2, ata66; struct pci_dev *pdev = to_pci_dev(ap->host->dev); pci_read_config_byte(pdev, 0x5B, &scr2); pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01); + + udelay(10); /* debounce */ + /* Cable register now active */ pci_read_config_byte(pdev, 0x5A, &ata66); /* Restore state */ pci_write_config_byte(pdev, 0x5B, scr2); - if (ata66 & (1 << ap->port_no)) - ap->cbl = ATA_CBL_PATA40; + if (ata66 & (2 >> ap->port_no)) + return ATA_CBL_PATA40; else - ap->cbl = ATA_CBL_PATA80; - - /* Reset the state machine */ - pci_write_config_byte(pdev, 0x50, 0x37); - pci_write_config_byte(pdev, 0x54, 0x37); - udelay(100); - - return ata_std_prereset(ap); + return ATA_CBL_PATA80; } /** - * hpt3x2n_error_handler - probe the hpt3x2n bus - * @ap: ATA port to reset + * hpt3x2n_pre_reset - reset the hpt3x2n bus + * @link: ATA link to reset + * @deadline: deadline jiffies for the operation * - * Perform the probe reset handling for the 3x2N + * Perform the initial reset handling for the 3x2n series controllers. + * Reset the hardware and state machine, */ -static void hpt3x2n_error_handler(struct ata_port *ap) +static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline) { - ata_bmdma_drive_eh(ap, hpt3xn_pre_reset, ata_std_softreset, NULL, ata_std_postreset); -} + struct ata_port *ap = link->ap; + struct pci_dev *pdev = to_pci_dev(ap->host->dev); -/** - * hpt3x2n_set_piomode - PIO setup - * @ap: ATA interface - * @adev: device on the interface - * - * Perform PIO mode setup. - */ + /* Reset the state machine */ + pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); + udelay(100); -static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) + return ata_sff_prereset(link, deadline); +} + +static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev, + u8 mode) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 addr1, addr2; - u32 reg; - u32 mode; + u32 reg, timing, mask; u8 fast; addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); @@ -183,12 +194,32 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) fast &= ~0x07; pci_write_config_byte(pdev, addr2, fast); + /* Determine timing mask and find matching mode entry */ + if (mode < XFER_MW_DMA_0) + mask = 0xcfc3ffff; + else if (mode < XFER_UDMA_0) + mask = 0x31c001ff; + else + mask = 0x303c0000; + + timing = hpt3x2n_find_mode(ap, mode); + pci_read_config_dword(pdev, addr1, ®); - mode = hpt3x2n_find_mode(ap, adev->pio_mode); - mode &= ~0x8000000; /* No FIFO in PIO */ - mode &= ~0x30070000; /* Leave config bits alone */ - reg &= 0x30070000; /* Strip timing bits */ - pci_write_config_dword(pdev, addr1, reg | mode); + reg = (reg & ~mask) | (timing & mask); + pci_write_config_dword(pdev, addr1, reg); +} + +/** + * hpt3x2n_set_piomode - PIO setup + * @ap: ATA interface + * @adev: device on the interface + * + * Perform PIO mode setup. + */ + +static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + hpt3x2n_set_mode(ap, adev, adev->pio_mode); } /** @@ -196,32 +227,12 @@ static void hpt3x2n_set_piomode(struct ata_port *ap, struct ata_device *adev) * @ap: ATA interface * @adev: Device being configured * - * Set up the channel for MWDMA or UDMA modes. Much the same as with - * PIO, load the mode number and then set MWDMA or UDMA flag. + * Set up the channel for MWDMA or UDMA modes. */ static void hpt3x2n_set_dmamode(struct ata_port *ap, struct ata_device *adev) { - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u32 addr1, addr2; - u32 reg; - u32 mode; - u8 fast; - - addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); - addr2 = 0x51 + 4 * ap->port_no; - - /* Fast interrupt prediction disable, hold off interrupt disable */ - pci_read_config_byte(pdev, addr2, &fast); - fast &= ~0x07; - pci_write_config_byte(pdev, addr2, fast); - - pci_read_config_dword(pdev, addr1, ®); - mode = hpt3x2n_find_mode(ap, adev->dma_mode); - mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ - mode &= ~0xC0000000; /* Leave config bits alone */ - reg &= 0xC0000000; /* Strip timing bits */ - pci_write_config_dword(pdev, addr1, reg | mode); + hpt3x2n_set_mode(ap, adev, adev->dma_mode); } /** @@ -263,124 +274,102 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc) static void hpt3x2n_set_clock(struct ata_port *ap, int source) { - unsigned long bmdma = ap->ioaddr.bmdma_addr; + void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8; /* Tristate the bus */ - outb(0x80, bmdma+0x73); - outb(0x80, bmdma+0x77); + iowrite8(0x80, bmdma+0x73); + iowrite8(0x80, bmdma+0x77); /* Switch clock and reset channels */ - outb(source, bmdma+0x7B); - outb(0xC0, bmdma+0x79); + iowrite8(source, bmdma+0x7B); + iowrite8(0xC0, bmdma+0x79); - /* Reset state machines */ - outb(0x37, bmdma+0x70); - outb(0x37, bmdma+0x74); + /* Reset state machines, avoid enabling the disabled channels */ + iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70); + iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74); /* Complete reset */ - outb(0x00, bmdma+0x79); + iowrite8(0x00, bmdma+0x79); /* Reconnect channels to bus */ - outb(0x00, bmdma+0x73); - outb(0x00, bmdma+0x77); -} - -/* Check if our partner interface is busy */ - -static int hpt3x2n_pair_idle(struct ata_port *ap) -{ - struct ata_host *host = ap->host; - struct ata_port *pair = host->ports[ap->port_no ^ 1]; - - if (pair->hsm_task_state == HSM_ST_IDLE) - return 1; - return 0; + iowrite8(0x00, bmdma+0x73); + iowrite8(0x00, bmdma+0x77); } -static int hpt3x2n_use_dpll(struct ata_port *ap, int reading) +static int hpt3x2n_use_dpll(struct ata_port *ap, int writing) { long flags = (long)ap->host->private_data; + /* See if we should use the DPLL */ - if (reading == 0) + if (writing) return USE_DPLL; /* Needed for write */ if (flags & PCI66) return USE_DPLL; /* Needed at 66Mhz */ return 0; } -static unsigned int hpt3x2n_qc_issue_prot(struct ata_queued_cmd *qc) +static int hpt3x2n_qc_defer(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ata_port *alt = ap->host->ports[ap->port_no ^ 1]; + int rc, flags = (long)ap->host->private_data; + int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE); + + /* First apply the usual rules */ + rc = ata_std_qc_defer(qc); + if (rc != 0) + return rc; + + if ((flags & USE_DPLL) != dpll && alt->qc_active) + return ATA_DEFER_PORT; + return 0; +} + +static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc) { - struct ata_taskfile *tf = &qc->tf; struct ata_port *ap = qc->ap; int flags = (long)ap->host->private_data; + int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE); - if (hpt3x2n_pair_idle(ap)) { - int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE)); - if ((flags & USE_DPLL) != dpll) { - if (dpll == 1) - hpt3x2n_set_clock(ap, 0x21); - else - hpt3x2n_set_clock(ap, 0x23); - } + if ((flags & USE_DPLL) != dpll) { + flags &= ~USE_DPLL; + flags |= dpll; + ap->host->private_data = (void *)(long)flags; + + hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23); } - return ata_qc_issue_prot(qc); + return ata_bmdma_qc_issue(qc); } static struct scsi_host_template hpt3x2n_sht = { - .module = THIS_MODULE, - .name = DRV_NAME, - .ioctl = ata_scsi_ioctl, - .queuecommand = ata_scsi_queuecmd, - .can_queue = ATA_DEF_QUEUE, - .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = LIBATA_MAX_PRD, - .max_sectors = ATA_MAX_SECTORS, - .cmd_per_lun = ATA_SHT_CMD_PER_LUN, - .emulated = ATA_SHT_EMULATED, - .use_clustering = ATA_SHT_USE_CLUSTERING, - .proc_name = DRV_NAME, - .dma_boundary = ATA_DMA_BOUNDARY, - .slave_configure = ata_scsi_slave_config, - .bios_param = ata_std_bios_param, + ATA_BMDMA_SHT(DRV_NAME), }; /* - * Configuration for HPT3x2n. + * Configuration for HPT302N/371N. */ -static struct ata_port_operations hpt3x2n_port_ops = { - .port_disable = ata_port_disable, - .set_piomode = hpt3x2n_set_piomode, - .set_dmamode = hpt3x2n_set_dmamode, - .mode_filter = ata_pci_default_filter, - - .tf_load = ata_tf_load, - .tf_read = ata_tf_read, - .check_status = ata_check_status, - .exec_command = ata_exec_command, - .dev_select = ata_std_dev_select, - - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = hpt3x2n_error_handler, - .post_internal_cmd = ata_bmdma_post_internal_cmd, +static struct ata_port_operations hpt3xxn_port_ops = { + .inherits = &ata_bmdma_port_ops, - .bmdma_setup = ata_bmdma_setup, - .bmdma_start = ata_bmdma_start, .bmdma_stop = hpt3x2n_bmdma_stop, - .bmdma_status = ata_bmdma_status, - .qc_prep = ata_qc_prep, - .qc_issue = hpt3x2n_qc_issue_prot, - .eng_timeout = ata_eng_timeout, - .data_xfer = ata_pio_data_xfer, + .qc_defer = hpt3x2n_qc_defer, + .qc_issue = hpt3x2n_qc_issue, - .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, + .cable_detect = hpt3x2n_cable_detect, + .set_piomode = hpt3x2n_set_piomode, + .set_dmamode = hpt3x2n_set_dmamode, + .prereset = hpt3x2n_pre_reset, +}; - .port_start = ata_port_start, - .port_stop = ata_port_stop, - .host_stop = ata_host_stop +/* + * Configuration for HPT372N. Same as 302N/371N but we have a mode filter. + */ + +static struct ata_port_operations hpt372n_port_ops = { + .inherits = &hpt3xxn_port_ops, + .mode_filter = &hpt372n_filter, }; /** @@ -397,12 +386,12 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev) u32 reg5c; int tries; - for(tries = 0; tries < 0x5000; tries++) { + for (tries = 0; tries < 0x5000; tries++) { udelay(50); pci_read_config_byte(dev, 0x5b, ®5b); if (reg5b & 0x80) { /* See if it stays set */ - for(tries = 0; tries < 0x1000; tries ++) { + for (tries = 0; tries < 0x1000; tries++) { pci_read_config_byte(dev, 0x5b, ®5b); /* Failed ? */ if ((reg5b & 0x80) == 0) @@ -410,7 +399,7 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev) } /* Turn off tuning, we have the DPLL set */ pci_read_config_dword(dev, 0x5c, ®5c); - pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); + pci_write_config_dword(dev, 0x5c, reg5c & ~0x100); return 1; } } @@ -422,11 +411,23 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) { unsigned long freq; u32 fcnt; + unsigned long iobase = pci_resource_start(pdev, 4); - pci_read_config_dword(pdev, 0x70/*CHECKME*/, &fcnt); + fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */ if ((fcnt >> 12) != 0xABCDE) { - printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n"); - return 33; /* Not BIOS set */ + int i; + u16 sr; + u32 total = 0; + + pr_warn("BIOS clock data not set\n"); + + /* This is the process the HPT371 BIOS is reported to use */ + for (i = 0; i < 128; i++) { + pci_read_config_word(pdev, 0x78, &sr); + total += sr & 0x1FF; + udelay(15); + } + fcnt = total / 128; } fcnt &= 0x1FF; @@ -468,53 +469,68 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) * HPT372N 9 (HPT372N) * UDMA133 * * (1) UDMA133 support depends on the bus clock - * - * To pin down HPT371N */ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - /* HPT372N and friends - UDMA133 */ - static struct ata_port_info info = { - .sht = &hpt3x2n_sht, - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, - .pio_mask = 0x1f, - .mwdma_mask = 0x07, - .udma_mask = 0x7f, - .port_ops = &hpt3x2n_port_ops + /* HPT372N - UDMA133 */ + static const struct ata_port_info info_hpt372n = { + .flags = ATA_FLAG_SLAVE_POSS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &hpt372n_port_ops }; - struct ata_port_info *port_info[2]; - struct ata_port_info *port = &info; - + /* HPT302N and HPT371N - UDMA133 */ + static const struct ata_port_info info_hpt3xxn = { + .flags = ATA_FLAG_SLAVE_POSS, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, + .udma_mask = ATA_UDMA6, + .port_ops = &hpt3xxn_port_ops + }; + const struct ata_port_info *ppi[] = { &info_hpt3xxn, NULL }; + u8 rev = dev->revision; u8 irqmask; - u32 class_rev; - unsigned int pci_mhz; unsigned int f_low, f_high; int adjust; - - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xFF; - - switch(dev->device) { - case PCI_DEVICE_ID_TTI_HPT366: - if (class_rev < 6) - return -ENODEV; - break; - case PCI_DEVICE_ID_TTI_HPT372: - /* 372N if rev >= 1*/ - if (class_rev == 0) - return -ENODEV; - break; - case PCI_DEVICE_ID_TTI_HPT302: - if (class_rev < 2) - return -ENODEV; - break; - case PCI_DEVICE_ID_TTI_HPT372N: - break; - default: - printk(KERN_ERR "pata_hpt3x2n: PCI table is bogus please report (%d).\n", dev->device); + unsigned long iobase = pci_resource_start(dev, 4); + void *hpriv = (void *)USE_DPLL; + int rc; + + rc = pcim_enable_device(dev); + if (rc) + return rc; + + switch (dev->device) { + case PCI_DEVICE_ID_TTI_HPT366: + /* 372N if rev >= 6 */ + if (rev < 6) + return -ENODEV; + goto hpt372n; + case PCI_DEVICE_ID_TTI_HPT371: + /* 371N if rev >= 2 */ + if (rev < 2) + return -ENODEV; + break; + case PCI_DEVICE_ID_TTI_HPT372: + /* 372N if rev >= 2 */ + if (rev < 2) + return -ENODEV; + goto hpt372n; + case PCI_DEVICE_ID_TTI_HPT302: + /* 302N if rev >= 2 */ + if (rev < 2) return -ENODEV; + break; + case PCI_DEVICE_ID_TTI_HPT372N: +hpt372n: + ppi[0] = &info_hpt372n; + break; + default: + pr_err("PCI table is bogus, please report (%d)\n", dev->device); + return -ENODEV; } /* Ok so this is a chip we support */ @@ -528,8 +544,23 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) irqmask &= ~0x10; pci_write_config_byte(dev, 0x5a, irqmask); - /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or - 50 for UDMA100. Right now we always use 66 */ + /* + * HPT371 chips physically have only one channel, the secondary one, + * but the primary channel registers do exist! Go figure... + * So, we manually disable the non-existing channel here + * (if the BIOS hasn't done this already). + */ + if (dev->device == PCI_DEVICE_ID_TTI_HPT371) { + u8 mcr1; + pci_read_config_byte(dev, 0x50, &mcr1); + mcr1 &= ~0x04; + pci_write_config_byte(dev, 0x50, mcr1); + } + + /* + * Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or + * 50 for UDMA100. Right now we always use 66 + */ pci_mhz = hpt3x2n_pci_clock(dev); @@ -541,57 +572,58 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_byte(dev, 0x5B, 0x21); /* Unlike the 37x we don't try jiggling the frequency */ - for(adjust = 0; adjust < 8; adjust++) { + for (adjust = 0; adjust < 8; adjust++) { if (hpt3xn_calibrate_dpll(dev)) break; pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); } - if (adjust == 8) - printk(KERN_WARNING "hpt3xn: DPLL did not stabilize.\n"); + if (adjust == 8) { + pr_err("DPLL did not stabilize!\n"); + return -ENODEV; + } + + pr_info("bus clock %dMHz, using 66MHz DPLL\n", pci_mhz); - /* Set our private data up. We only need a few flags so we use - it directly */ - port->private_data = NULL; + /* + * Set our private data up. We only need a few flags + * so we use it directly. + */ if (pci_mhz > 60) - port->private_data = (void *)PCI66; + hpriv = (void *)(PCI66 | USE_DPLL); + + /* + * On HPT371N, if ATA clock is 66 MHz we must set bit 2 in + * the MISC. register to stretch the UltraDMA Tss timing. + * NOTE: This register is only writeable via I/O space. + */ + if (dev->device == PCI_DEVICE_ID_TTI_HPT371) + outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c); /* Now kick off ATA set up */ - port_info[0] = port_info[1] = port; - return ata_pci_init_one(dev, port_info, 2); + return ata_pci_bmdma_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0); } -static struct pci_device_id hpt3x2n[] = { - { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), }, - { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), }, - { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), }, - { PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372N), }, - { 0, }, +static const struct pci_device_id hpt3x2n[] = { + { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, + { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), }, + { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), }, + { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), }, + { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), }, + + { }, }; static struct pci_driver hpt3x2n_pci_driver = { - .name = DRV_NAME, + .name = DRV_NAME, .id_table = hpt3x2n, - .probe = hpt3x2n_init_one, + .probe = hpt3x2n_init_one, .remove = ata_pci_remove_one }; -static int __init hpt3x2n_init(void) -{ - return pci_register_driver(&hpt3x2n_pci_driver); -} - - -static void __exit hpt3x2n_exit(void) -{ - pci_unregister_driver(&hpt3x2n_pci_driver); -} - +module_pci_driver(hpt3x2n_pci_driver); MODULE_AUTHOR("Alan Cox"); -MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3x2n/30x"); +MODULE_DESCRIPTION("low-level driver for the Highpoint HPT3xxN"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, hpt3x2n); MODULE_VERSION(DRV_VERSION); - -module_init(hpt3x2n_init); -module_exit(hpt3x2n_exit); |
