Commit 1542dec1 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  pata_platform: Remove CONFIG_HAVE_PATA_PLATFORM's dependencies.
  pata_hpt37x: actually limit HPT370 to UltraDMA/66
  pata_hpt3x2n: coding style cleanup
  pata_hpt37x: coding style cleanup
  pata_hpt366: coding style cleanup
  pata_hpt3x2n: calculate average f_CNT
  pata_hpt3x2n: clarify about HPT371N support
  pata_hpt{37x|3x2n}: SATA mode filtering
  [libata] avoid needlessly passing around ptr to SCSI completion func
  [libata] new driver acard_ahci, for ATP8620 host controller
parents facc7a96 2ad2c320
...@@ -2,6 +2,14 @@ ...@@ -2,6 +2,14 @@
# SATA/PATA driver configuration # SATA/PATA driver configuration
# #
config HAVE_PATA_PLATFORM
bool
help
This is an internal configuration node for any machine that
uses pata-platform driver to enable the relevant driver in the
configuration structure without having to submit endless patches
to update the PATA_PLATFORM entry.
menuconfig ATA menuconfig ATA
tristate "Serial ATA and Parallel ATA drivers" tristate "Serial ATA and Parallel ATA drivers"
depends on HAS_IOMEM depends on HAS_IOMEM
...@@ -90,6 +98,14 @@ config SATA_INIC162X ...@@ -90,6 +98,14 @@ config SATA_INIC162X
help help
This option enables support for Initio 162x Serial ATA. This option enables support for Initio 162x Serial ATA.
config SATA_ACARD_AHCI
tristate "ACard AHCI variant (ATP 8620)"
depends on PCI
help
This option enables support for Acard.
If unsure, say N.
config SATA_SIL24 config SATA_SIL24
tristate "Silicon Image 3124/3132 SATA support" tristate "Silicon Image 3124/3132 SATA support"
depends on PCI depends on PCI
...@@ -400,11 +416,11 @@ config PATA_HPT37X ...@@ -400,11 +416,11 @@ config PATA_HPT37X
If unsure, say N. If unsure, say N.
config PATA_HPT3X2N config PATA_HPT3X2N
tristate "HPT 372N/302N PATA support" tristate "HPT 371N/372N/302N PATA support"
depends on PCI depends on PCI
help help
This option enables support for the N variant HPT PATA This option enables support for the N variant HPT PATA
controllers via the new ATA layer controllers via the new ATA layer.
If unsure, say N. If unsure, say N.
...@@ -765,14 +781,6 @@ config PATA_PCMCIA ...@@ -765,14 +781,6 @@ config PATA_PCMCIA
If unsure, say N. If unsure, say N.
config HAVE_PATA_PLATFORM
bool
help
This is an internal configuration node for any machine that
uses pata-platform driver to enable the relevant driver in the
configuration structure without having to submit endless patches
to update the PATA_PLATFORM entry.
config PATA_PLATFORM config PATA_PLATFORM
tristate "Generic platform device PATA support" tristate "Generic platform device PATA support"
depends on EMBEDDED || PPC || HAVE_PATA_PLATFORM depends on EMBEDDED || PPC || HAVE_PATA_PLATFORM
......
...@@ -3,6 +3,7 @@ obj-$(CONFIG_ATA) += libata.o ...@@ -3,6 +3,7 @@ obj-$(CONFIG_ATA) += libata.o
# non-SFF interface # non-SFF interface
obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o
obj-$(CONFIG_SATA_ACARD_AHCI) += acard-ahci.o libahci.o
obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
obj-$(CONFIG_SATA_FSL) += sata_fsl.o obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
......
/*
* acard-ahci.c - ACard AHCI SATA support
*
* Maintained by: Jeff Garzik <jgarzik@pobox.com>
* Please ALWAYS copy linux-ide@vger.kernel.org
* on emails.
*
* Copyright 2010 Red Hat, Inc.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* libata documentation is available via 'make {ps|pdf}docs',
* as Documentation/DocBook/libata.*
*
* AHCI hardware documentation:
* http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
* http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
*
*/
#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 <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/gfp.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
#include "ahci.h"
#define DRV_NAME "acard-ahci"
#define DRV_VERSION "1.0"
/*
Received FIS structure limited to 80h.
*/
#define ACARD_AHCI_RX_FIS_SZ 128
enum {
AHCI_PCI_BAR = 5,
};
enum board_ids {
board_acard_ahci,
};
struct acard_sg {
__le32 addr;
__le32 addr_hi;
__le32 reserved;
__le32 size; /* bit 31 (EOT) max==0x10000 (64k) */
};
static void acard_ahci_qc_prep(struct ata_queued_cmd *qc);
static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
static int acard_ahci_port_start(struct ata_port *ap);
static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
#ifdef CONFIG_PM
static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int acard_ahci_pci_device_resume(struct pci_dev *pdev);
#endif
static struct scsi_host_template acard_ahci_sht = {
AHCI_SHT("acard-ahci"),
};
static struct ata_port_operations acard_ops = {
.inherits = &ahci_ops,
.qc_prep = acard_ahci_qc_prep,
.qc_fill_rtf = acard_ahci_qc_fill_rtf,
.port_start = acard_ahci_port_start,
};
#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
static const struct ata_port_info acard_ahci_port_info[] = {
[board_acard_ahci] =
{
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ),
.flags = AHCI_FLAG_COMMON,
.pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &acard_ops,
},
};
static const struct pci_device_id acard_ahci_pci_tbl[] = {
/* ACard */
{ PCI_VDEVICE(ARTOP, 0x000d), board_acard_ahci }, /* ATP8620 */
{ } /* terminate list */
};
static struct pci_driver acard_ahci_pci_driver = {
.name = DRV_NAME,
.id_table = acard_ahci_pci_tbl,
.probe = acard_ahci_init_one,
.remove = ata_pci_remove_one,
#ifdef CONFIG_PM
.suspend = acard_ahci_pci_device_suspend,
.resume = acard_ahci_pci_device_resume,
#endif
};
#ifdef CONFIG_PM
static int acard_ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
struct ahci_host_priv *hpriv = host->private_data;
void __iomem *mmio = hpriv->mmio;
u32 ctl;
if (mesg.event & PM_EVENT_SUSPEND &&
hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
dev_printk(KERN_ERR, &pdev->dev,
"BIOS update required for suspend/resume\n");
return -EIO;
}
if (mesg.event & PM_EVENT_SLEEP) {
/* AHCI spec rev1.1 section 8.3.3:
* Software must disable interrupts prior to requesting a
* transition of the HBA to D3 state.
*/
ctl = readl(mmio + HOST_CTL);
ctl &= ~HOST_IRQ_EN;
writel(ctl, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */
}
return ata_pci_device_suspend(pdev, mesg);
}
static int acard_ahci_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
int rc;
rc = ata_pci_device_do_resume(pdev);
if (rc)
return rc;
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
rc = ahci_reset_controller(host);
if (rc)
return rc;
ahci_init_controller(host);
}
ata_host_resume(host);
return 0;
}
#endif
static int acard_ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
{
int rc;
if (using_dac &&
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (rc) {
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"64-bit DMA enable failed\n");
return rc;
}
}
} else {
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit consistent DMA enable failed\n");
return rc;
}
}
return 0;
}
static void acard_ahci_pci_print_info(struct ata_host *host)
{
struct pci_dev *pdev = to_pci_dev(host->dev);
u16 cc;
const char *scc_s;
pci_read_config_word(pdev, 0x0a, &cc);
if (cc == PCI_CLASS_STORAGE_IDE)
scc_s = "IDE";
else if (cc == PCI_CLASS_STORAGE_SATA)
scc_s = "SATA";
else if (cc == PCI_CLASS_STORAGE_RAID)
scc_s = "RAID";
else
scc_s = "unknown";
ahci_print_info(host, scc_s);
}
static unsigned int acard_ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl)
{
struct scatterlist *sg;
struct acard_sg *acard_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ;
unsigned int si, last_si = 0;
VPRINTK("ENTER\n");
/*
* Next, the S/G list.
*/
for_each_sg(qc->sg, sg, qc->n_elem, si) {
dma_addr_t addr = sg_dma_address(sg);
u32 sg_len = sg_dma_len(sg);
/*
* ACard note:
* We must set an end-of-table (EOT) bit,
* and the segment cannot exceed 64k (0x10000)
*/
acard_sg[si].addr = cpu_to_le32(addr & 0xffffffff);
acard_sg[si].addr_hi = cpu_to_le32((addr >> 16) >> 16);
acard_sg[si].size = cpu_to_le32(sg_len);
last_si = si;
}
acard_sg[last_si].size |= cpu_to_le32(1 << 31); /* set EOT */
return si;
}
static void acard_ahci_qc_prep(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ahci_port_priv *pp = ap->private_data;
int is_atapi = ata_is_atapi(qc->tf.protocol);
void *cmd_tbl;
u32 opts;
const u32 cmd_fis_len = 5; /* five dwords */
unsigned int n_elem;
/*
* Fill in command table information. First, the header,
* a SATA Register - Host to Device command FIS.
*/
cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ;
ata_tf_to_fis(&qc->tf, qc->dev->link->pmp, 1, cmd_tbl);
if (is_atapi) {
memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len);
}
n_elem = 0;
if (qc->flags & ATA_QCFLAG_DMAMAP)
n_elem = acard_ahci_fill_sg(qc, cmd_tbl);
/*
* Fill in command slot information.
*
* ACard note: prd table length not filled in
*/
opts = cmd_fis_len | (qc->dev->link->pmp << 12);
if (qc->tf.flags & ATA_TFLAG_WRITE)
opts |= AHCI_CMD_WRITE;
if (is_atapi)
opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH;
ahci_fill_cmd_slot(pp, qc->tag, opts);
}
static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
{
struct ahci_port_priv *pp = qc->ap->private_data;
u8 *rx_fis = pp->rx_fis;
if (pp->fbs_enabled)
rx_fis += qc->dev->link->pmp * ACARD_AHCI_RX_FIS_SZ;
/*
* After a successful execution of an ATA PIO data-in command,
* the device doesn't send D2H Reg FIS to update the TF and
* the host should take TF and E_Status from the preceding PIO
* Setup FIS.
*/
if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE &&
!(qc->flags & ATA_QCFLAG_FAILED)) {
ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15];
} else
ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
return true;
}
static int acard_ahci_port_start(struct ata_port *ap)
{
struct ahci_host_priv *hpriv = ap->host->private_data;
struct device *dev = ap->host->dev;
struct ahci_port_priv *pp;
void *mem;
dma_addr_t mem_dma;
size_t dma_sz, rx_fis_sz;
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
/* check FBS capability */
if ((hpriv->cap & HOST_CAP_FBS) && sata_pmp_supported(ap)) {
void __iomem *port_mmio = ahci_port_base(ap);
u32 cmd = readl(port_mmio + PORT_CMD);
if (cmd & PORT_CMD_FBSCP)
pp->fbs_supported = true;
else if (hpriv->flags & AHCI_HFLAG_YES_FBS) {
dev_printk(KERN_INFO, dev,
"port %d can do FBS, forcing FBSCP\n",
ap->port_no);
pp->fbs_supported = true;
} else
dev_printk(KERN_WARNING, dev,
"port %d is not capable of FBS\n",
ap->port_no);
}
if (pp->fbs_supported) {
dma_sz = AHCI_PORT_PRIV_FBS_DMA_SZ;
rx_fis_sz = ACARD_AHCI_RX_FIS_SZ * 16;
} else {
dma_sz = AHCI_PORT_PRIV_DMA_SZ;
rx_fis_sz = ACARD_AHCI_RX_FIS_SZ;
}
mem = dmam_alloc_coherent(dev, dma_sz, &mem_dma, GFP_KERNEL);
if (!mem)
return -ENOMEM;
memset(mem, 0, dma_sz);
/*
* First item in chunk of DMA memory: 32-slot command table,
* 32 bytes each in size
*/
pp->cmd_slot = mem;
pp->cmd_slot_dma = mem_dma;
mem += AHCI_CMD_SLOT_SZ;
mem_dma += AHCI_CMD_SLOT_SZ;
/*
* Second item: Received-FIS area
*/
pp->rx_fis = mem;
pp->rx_fis_dma = mem_dma;
mem += rx_fis_sz;
mem_dma += rx_fis_sz;
/*
* Third item: data area for storing a single command
* and its scatter-gather table
*/
pp->cmd_tbl = mem;
pp->cmd_tbl_dma = mem_dma;
/*
* Save off initial list of interrupts to be enabled.
* This could be changed later
*/
pp->intr_mask = DEF_PORT_IRQ;
ap->private_data = pp;
/* engage engines, captain */
return ahci_port_resume(ap);
}
static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
unsigned int board_id = ent->driver_data;
struct ata_port_info pi = acard_ahci_port_info[board_id];
const struct ata_port_info *ppi[] = { &pi, NULL };
struct device *dev = &pdev->dev;
struct ahci_host_priv *hpriv;
struct ata_host *host;
int n_ports, i, rc;
VPRINTK("ENTER\n");
WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS);
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/* acquire resources */
rc = pcim_enable_device(pdev);
if (rc)
return rc;
/* AHCI controllers often implement SFF compatible interface.
* Grab all PCI BARs just in case.
*/
rc = pcim_iomap_regions_request_all(pdev, 1 << AHCI_PCI_BAR, DRV_NAME);
if (rc == -EBUSY)
pcim_pin_device(pdev);
if (rc)
return rc;
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
hpriv->flags |= (unsigned long)pi.private_data;
if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
pci_enable_msi(pdev);
hpriv->mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
/* save initial config */
ahci_save_initial_config(&pdev->dev, hpriv, 0, 0);
/* prepare host */
if (hpriv->cap & HOST_CAP_NCQ)
pi.flags |= ATA_FLAG_NCQ;
if (hpriv->cap & HOST_CAP_PMP)
pi.flags |= ATA_FLAG_PMP;
ahci_set_em_messages(hpriv, &pi);
/* CAP.NP sometimes indicate the index of the last enabled
* port, at other times, that of the last possible port, so
* determining the maximum port number requires looking at
* both CAP.NP and port_map.
*/
n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
if (!host)
return -ENOMEM;
host->private_data = hpriv;
if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
host->flags |= ATA_HOST_PARALLEL_SCAN;
else
printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n");
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar");
ata_port_pbar_desc(ap, AHCI_PCI_BAR,
0x100 + ap->port_no * 0x80, "port");
/* set initial link pm policy */
/*
ap->pm_policy = NOT_AVAILABLE;
*/
/* disabled/not-implemented port */
if (!(hpriv->port_map & (1 << i)))
ap->ops = &ata_dummy_port_ops;
}
/* initialize adapter */
rc = acard_ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
if (rc)
return rc;
rc = ahci_reset_controller(host);
if (rc)
return rc;
ahci_init_controller(host);
acard_ahci_pci_print_info(host);
pci_set_master(pdev);
return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
&acard_ahci_sht);
}
static int __init acard_ahci_init(void)
{
return pci_register_driver(&acard_ahci_pci_driver);
}
static void __exit acard_ahci_exit(void)
{
pci_unregister_driver(&acard_ahci_pci_driver);
}
MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("ACard AHCI SATA low-level driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, acard_ahci_pci_tbl);
MODULE_VERSION(DRV_VERSION);
module_init(acard_ahci_init);
module_exit(acard_ahci_exit);
...@@ -311,6 +311,8 @@ extern struct device_attribute *ahci_sdev_attrs[]; ...@@ -311,6 +311,8 @@ extern struct device_attribute *ahci_sdev_attrs[];
extern struct ata_port_operations ahci_ops; extern struct ata_port_operations ahci_ops;
void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
u32 opts);
void ahci_save_initial_config(struct device *dev, void ahci_save_initial_config(struct device *dev,
struct ahci_host_priv *hpriv, struct ahci_host_priv *hpriv,
unsigned int force_port_map, unsigned int force_port_map,
...@@ -326,6 +328,7 @@ int ahci_stop_engine(struct ata_port *ap); ...@@ -326,6 +328,7 @@ int ahci_stop_engine(struct ata_port *ap);
void ahci_start_engine(struct ata_port *ap); void ahci_start_engine(struct ata_port *ap);
int ahci_check_ready(struct ata_link *link); int ahci_check_ready(struct ata_link *link);
int ahci_kick_engine(struct ata_port *ap); int ahci_kick_engine(struct ata_port *ap);
int ahci_port_resume(struct ata_port *ap);
void ahci_set_em_messages(struct ahci_host_priv *hpriv, void ahci_set_em_messages(struct ahci_host_priv *hpriv,
struct ata_port_info *pi); struct ata_port_info *pi);
int ahci_reset_em(struct ata_host *host); int ahci_reset_em(struct ata_host *host);
......
...@@ -87,10 +87,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class, ...@@ -87,10 +87,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
static void ahci_postreset(struct ata_link *link, unsigned int *class); static void ahci_postreset(struct ata_link *link, unsigned int *class);
static void ahci_error_handler(struct ata_port *ap); static void ahci_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
static int ahci_port_resume(struct ata_port *ap);
static void ahci_dev_config(struct ata_device *dev); static void ahci_dev_config(struct ata_device *dev);
static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
u32 opts);
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
#endif #endif
...@@ -1133,7 +1130,7 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) ...@@ -1133,7 +1130,7 @@ static unsigned int ahci_dev_classify(struct ata_port *ap)
return ata_dev_classify(&tf); return ata_dev_classify(&tf);
} }
static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
u32 opts) u32 opts)
{ {
dma_addr_t cmd_tbl_dma; dma_addr_t cmd_tbl_dma;
...@@ -1145,6 +1142,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, ...@@ -1145,6 +1142,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff); pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff);
pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16);
} }
EXPORT_SYMBOL_GPL(ahci_fill_cmd_slot);
int ahci_kick_engine(struct ata_port *ap) int ahci_kick_engine(struct ata_port *ap)
{ {
...@@ -1918,7 +1916,7 @@ static void ahci_pmp_detach(struct ata_port *ap) ...@@ -1918,7 +1916,7 @@ static void ahci_pmp_detach(struct ata_port *ap)
writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
} }
static int ahci_port_resume(struct ata_port *ap) int ahci_port_resume(struct ata_port *ap)
{ {
ahci_power_up(ap); ahci_power_up(ap);
ahci_start_port(ap); ahci_start_port(ap);
...@@ -1930,6 +1928,7 @@ static int ahci_port_resume(struct ata_port *ap) ...@@ -1930,6 +1928,7 @@ static int ahci_port_resume(struct ata_port *ap)
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(ahci_port_resume);
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
......
...@@ -346,12 +346,11 @@ struct device_attribute *ata_common_sdev_attrs[] = { ...@@ -346,12 +346,11 @@ struct device_attribute *ata_common_sdev_attrs[] = {
}; };
EXPORT_SYMBOL_GPL(ata_common_sdev_attrs); EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, static void ata_scsi_invalid_field(struct scsi_cmnd *cmd)
void (*done)(struct scsi_cmnd *))
{ {
ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0); ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0);
/* "Invalid field in cbd" */ /* "Invalid field in cbd" */
done(cmd); cmd->scsi_done(cmd);
} }
/** /**
...@@ -719,7 +718,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl); ...@@ -719,7 +718,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
* ata_scsi_qc_new - acquire new ata_queued_cmd reference * ata_scsi_qc_new - acquire new ata_queued_cmd reference
* @dev: ATA device to which the new command is attached * @dev: ATA device to which the new command is attached
* @cmd: SCSI command that originated this ATA command * @cmd: SCSI command that originated this ATA command
* @done: SCSI command completion function
* *
* Obtain a reference to an unused ata_queued_cmd structure, * Obtain a reference to an unused ata_queued_cmd structure,
* which is the basic libata structure representing a single * which is the basic libata structure representing a single
...@@ -736,21 +734,20 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl); ...@@ -736,21 +734,20 @@ EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
* Command allocated, or %NULL if none available. * Command allocated, or %NULL if none available.
*/ */
static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
struct scsi_cmnd *cmd, struct scsi_cmnd *cmd)
void (*done)(struct scsi_cmnd *))
{ {
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
qc = ata_qc_new_init(dev); qc = ata_qc_new_init(dev);
if (qc) { if (qc) {
qc->scsicmd = cmd; qc->scsicmd = cmd;
qc->scsidone = done; qc->scsidone = cmd->scsi_done;
qc->sg = scsi_sglist(cmd); qc->sg = scsi_sglist(cmd);
qc->n_elem = scsi_sg_count(cmd); qc->n_elem = scsi_sg_count(cmd);
} else { } else {
cmd->result = (DID_OK << 16) | (QUEUE_FULL << 1); cmd->result = (DID_OK << 16) | (QUEUE_FULL << 1);
done(cmd); cmd->scsi_done(cmd);
} }
return qc; return qc;
...@@ -1735,7 +1732,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) ...@@ -1735,7 +1732,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
* ata_scsi_translate - Translate then issue SCSI command to ATA device * ata_scsi_translate - Translate then issue SCSI command to ATA device
* @dev: ATA device to which the command is addressed * @dev: ATA device to which the command is addressed
* @cmd: SCSI command to execute * @cmd: SCSI command to execute
* @done: SCSI command completion function
* @xlat_func: Actor which translates @cmd to an ATA taskfile * @xlat_func: Actor which translates @cmd to an ATA taskfile
* *
* Our ->queuecommand() function has decided that the SCSI * Our ->queuecommand() function has decided that the SCSI
...@@ -1759,7 +1755,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) ...@@ -1759,7 +1755,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
* needs to be deferred. * needs to be deferred.
*/ */
static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *),
ata_xlat_func_t xlat_func) ata_xlat_func_t xlat_func)
{ {
struct ata_port *ap = dev->link->ap; struct ata_port *ap = dev->link->ap;
...@@ -1768,7 +1763,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, ...@@ -1768,7 +1763,7 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
VPRINTK("ENTER\n"); VPRINTK("ENTER\n");
qc = ata_scsi_qc_new(dev, cmd, done); qc = ata_scsi_qc_new(dev, cmd);
if (!qc) if (!qc)
goto err_mem; goto err_mem;
...@@ -1804,14 +1799,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, ...@@ -1804,14 +1799,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
early_finish: early_finish:
ata_qc_free(qc); ata_qc_free(qc);
qc->scsidone(cmd); cmd->scsi_done(cmd);
DPRINTK("EXIT - early finish (good or error)\n"); DPRINTK("EXIT - early finish (good or error)\n");
return 0; return 0;
err_did: err_did:
ata_qc_free(qc); ata_qc_free(qc);
cmd->result = (DID_ERROR << 16); cmd->result = (DID_ERROR << 16);
qc->scsidone(cmd); cmd->scsi_done(cmd);
err_mem: err_mem:
DPRINTK("EXIT - internal\n"); DPRINTK("EXIT - internal\n");
return 0; return 0;
...@@ -3116,7 +3111,6 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap, ...@@ -3116,7 +3111,6 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
} }
static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
void (*done)(struct scsi_cmnd *),
struct ata_device *dev) struct ata_device *dev)
{ {
u8 scsi_op = scmd->cmnd[0]; u8 scsi_op = scmd->cmnd[0];
...@@ -3150,9 +3144,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, ...@@ -3150,9 +3144,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
} }
if (xlat_func) if (xlat_func)
rc = ata_scsi_translate(dev, scmd, done, xlat_func); rc = ata_scsi_translate(dev, scmd, xlat_func);
else else
ata_scsi_simulate(dev, scmd, done); ata_scsi_simulate(dev, scmd);
return rc; return rc;
...@@ -3160,7 +3154,7 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, ...@@ -3160,7 +3154,7 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n", DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n",
scmd->cmd_len, scsi_op, dev->cdb_len); scmd->cmd_len, scsi_op, dev->cdb_len);
scmd->result = DID_ERROR << 16; scmd->result = DID_ERROR << 16;
done(scmd); scmd->scsi_done(scmd);
return 0; return 0;
} }
...@@ -3199,7 +3193,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) ...@@ -3199,7 +3193,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
dev = ata_scsi_find_dev(ap, scsidev); dev = ata_scsi_find_dev(ap, scsidev);
if (likely(dev)) if (likely(dev))
rc = __ata_scsi_queuecmd(cmd, cmd->scsi_done, dev); rc = __ata_scsi_queuecmd(cmd, dev);
else { else {
cmd->result = (DID_BAD_TARGET << 16); cmd->result = (DID_BAD_TARGET << 16);
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
...@@ -3214,7 +3208,6 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) ...@@ -3214,7 +3208,6 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
* ata_scsi_simulate - simulate SCSI command on ATA device * ata_scsi_simulate - simulate SCSI command on ATA device
* @dev: the target device * @dev: the target device
* @cmd: SCSI command being sent to device. * @cmd: SCSI command being sent to device.
* @done: SCSI command completion function.
* *
* Interprets and directly executes a select list of SCSI commands * Interprets and directly executes a select list of SCSI commands
* that can be handled internally. * that can be handled internally.
...@@ -3223,8 +3216,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) ...@@ -3223,8 +3216,7 @@ int ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
* spin_lock_irqsave(host lock) * spin_lock_irqsave(host lock)
*/ */
void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
void (*done)(struct scsi_cmnd *))
{ {
struct ata_scsi_args args; struct ata_scsi_args args;
const u8 *scsicmd = cmd->cmnd; const u8 *scsicmd = cmd->cmnd;
...@@ -3233,17 +3225,17 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, ...@@ -3233,17 +3225,17 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
args.dev = dev; args.dev = dev;
args.id = dev->id; args.id = dev->id;
args.cmd = cmd; args.cmd = cmd;
args.done = done; args.done = cmd->scsi_done;
switch(scsicmd[0]) { switch(scsicmd[0]) {
/* TODO: worth improving? */ /* TODO: worth improving? */
case FORMAT_UNIT: case FORMAT_UNIT:
ata_scsi_invalid_field(cmd, done); ata_scsi_invalid_field(cmd);
break; break;
case INQUIRY: case INQUIRY:
if (scsicmd[1] & 2) /* is CmdDt set? */ if (scsicmd[1] & 2) /* is CmdDt set? */
ata_scsi_invalid_field(cmd, done); ata_scsi_invalid_field(cmd);
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
else switch (scsicmd[2]) { else switch (scsicmd[2]) {
...@@ -3269,7 +3261,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, ...@@ -3269,7 +3261,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2); ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
break; break;
default: default:
ata_scsi_invalid_field(cmd, done); ata_scsi_invalid_field(cmd);
break; break;
} }
break; break;
...@@ -3281,7 +3273,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, ...@@ -3281,7 +3273,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
case MODE_SELECT: /* unconditionally return */ case MODE_SELECT: /* unconditionally return */
case MODE_SELECT_10: /* bad-field-in-cdb */ case MODE_SELECT_10: /* bad-field-in-cdb */
ata_scsi_invalid_field(cmd, done); ata_scsi_invalid_field(cmd);
break; break;
case READ_CAPACITY: case READ_CAPACITY:
...@@ -3292,7 +3284,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, ...@@ -3292,7 +3284,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
else else
ata_scsi_invalid_field(cmd, done); ata_scsi_invalid_field(cmd);
break; break;
case REPORT_LUNS: case REPORT_LUNS:
...@@ -3302,7 +3294,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, ...@@ -3302,7 +3294,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
case REQUEST_SENSE: case REQUEST_SENSE:
ata_scsi_set_sense(cmd, 0, 0, 0); ata_scsi_set_sense(cmd, 0, 0, 0);
cmd->result = (DRIVER_SENSE << 24); cmd->result = (DRIVER_SENSE << 24);
done(cmd); cmd->scsi_done(cmd);
break; break;
/* if we reach this, then writeback caching is disabled, /* if we reach this, then writeback caching is disabled,
...@@ -3324,14 +3316,14 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, ...@@ -3324,14 +3316,14 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4])) if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4]))
ata_scsi_rbuf_fill(&args, ata_scsiop_noop); ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
else else
ata_scsi_invalid_field(cmd, done); ata_scsi_invalid_field(cmd);
break; break;
/* all other commands */ /* all other commands */
default: default:
ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0); ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0);
/* "Invalid command operation code" */ /* "Invalid command operation code" */
done(cmd); cmd->scsi_done(cmd);
break; break;
} }
} }
...@@ -3858,7 +3850,6 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure); ...@@ -3858,7 +3850,6 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure);
/** /**
* ata_sas_queuecmd - Issue SCSI cdb to libata-managed device * ata_sas_queuecmd - Issue SCSI cdb to libata-managed device
* @cmd: SCSI command to be sent * @cmd: SCSI command to be sent
* @done: Completion function, called when command is complete
* @ap: ATA port to which the command is being sent * @ap: ATA port to which the command is being sent
* *
* RETURNS: * RETURNS:
...@@ -3866,18 +3857,17 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure); ...@@ -3866,18 +3857,17 @@ EXPORT_SYMBOL_GPL(ata_sas_slave_configure);
* 0 otherwise. * 0 otherwise.
*/ */
int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap)
struct ata_port *ap)
{ {
int rc = 0; int rc = 0;
ata_scsi_dump_cdb(ap, cmd); ata_scsi_dump_cdb(ap, cmd);
if (likely(ata_dev_enabled(ap->link.device))) if (likely(ata_dev_enabled(ap->link.device)))
rc = __ata_scsi_queuecmd(cmd, done, ap->link.device); rc = __ata_scsi_queuecmd(cmd, ap->link.device);
else { else {
cmd->result = (DID_BAD_TARGET << 16); cmd->result = (DID_BAD_TARGET << 16);
done(cmd); cmd->scsi_done(cmd);
} }
return rc; return rc;
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "pata_hpt366" #define DRV_NAME "pata_hpt366"
#define DRV_VERSION "0.6.8" #define DRV_VERSION "0.6.9"
struct hpt_clock { struct hpt_clock {
u8 xfer_mode; u8 xfer_mode;
...@@ -110,18 +110,23 @@ static const struct hpt_clock hpt366_25[] = { ...@@ -110,18 +110,23 @@ static const struct hpt_clock hpt366_25[] = {
{ 0, 0x01208585 } { 0, 0x01208585 }
}; };
static const char *bad_ata33[] = { static const char * const bad_ata33[] = {
"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3",
"Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", "Maxtor 90845U3", "Maxtor 90650U2",
"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5",
"Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6",
"Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
"Maxtor 90510D4", "Maxtor 90510D4",
"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
"Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7",
"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5",
"Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
NULL NULL
}; };
static const char *bad_ata66_4[] = { static const char * const bad_ata66_4[] = {
"IBM-DTLA-307075", "IBM-DTLA-307075",
"IBM-DTLA-307060", "IBM-DTLA-307060",
"IBM-DTLA-307045", "IBM-DTLA-307045",
...@@ -140,12 +145,13 @@ static const char *bad_ata66_4[] = { ...@@ -140,12 +145,13 @@ static const char *bad_ata66_4[] = {
NULL NULL
}; };
static const char *bad_ata66_3[] = { static const char * const bad_ata66_3[] = {
"WDC AC310200R", "WDC AC310200R",
NULL NULL
}; };
static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr,
const char * const list[])
{ {
unsigned char model_num[ATA_ID_PROD_LEN + 1]; unsigned char model_num[ATA_ID_PROD_LEN + 1];
int i = 0; int i = 0;
...@@ -288,6 +294,7 @@ static struct ata_port_operations hpt366_port_ops = { ...@@ -288,6 +294,7 @@ static struct ata_port_operations hpt366_port_ops = {
static void hpt36x_init_chipset(struct pci_dev *dev) static void hpt36x_init_chipset(struct pci_dev *dev)
{ {
u8 drive_fast; u8 drive_fast;
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
...@@ -349,7 +356,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -349,7 +356,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* PCI clocking determines the ATA timing values to use */ /* PCI clocking determines the ATA timing values to use */
/* info_hpt366 is safe against re-entry so we can scribble on it */ /* info_hpt366 is safe against re-entry so we can scribble on it */
switch((reg1 & 0x700) >> 8) { switch ((reg1 & 0x700) >> 8) {
case 9: case 9:
hpriv = &hpt366_40; hpriv = &hpt366_40;
break; break;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc * Portions Copyright (C) 2003 Red Hat Inc
* Portions Copyright (C) 2005-2009 MontaVista Software, Inc. * Portions Copyright (C) 2005-2010 MontaVista Software, Inc.
* *
* TODO * TODO
* Look into engine reset on timeout errors. Should not be required. * Look into engine reset on timeout errors. Should not be required.
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "pata_hpt37x" #define DRV_NAME "pata_hpt37x"
#define DRV_VERSION "0.6.15" #define DRV_VERSION "0.6.18"
struct hpt_clock { struct hpt_clock {
u8 xfer_speed; u8 xfer_speed;
...@@ -210,7 +210,7 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed) ...@@ -210,7 +210,7 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
{ {
struct hpt_clock *clocks = ap->host->private_data; struct hpt_clock *clocks = ap->host->private_data;
while(clocks->xfer_speed) { while (clocks->xfer_speed) {
if (clocks->xfer_speed == speed) if (clocks->xfer_speed == speed)
return clocks->timing; return clocks->timing;
clocks++; clocks++;
...@@ -219,7 +219,8 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed) ...@@ -219,7 +219,8 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
return 0xffffffffU; /* silence compiler warning */ return 0xffffffffU; /* silence compiler warning */
} }
static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[]) static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr,
const char * const list[])
{ {
unsigned char model_num[ATA_ID_PROD_LEN + 1]; unsigned char model_num[ATA_ID_PROD_LEN + 1];
int i = 0; int i = 0;
...@@ -237,18 +238,23 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, cons ...@@ -237,18 +238,23 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, cons
return 0; return 0;
} }
static const char *bad_ata33[] = { static const char * const bad_ata33[] = {
"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3",
"Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", "Maxtor 90845U3", "Maxtor 90650U2",
"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5",
"Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6",
"Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
"Maxtor 90510D4", "Maxtor 90510D4",
"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
"Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7",
"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5",
"Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
NULL NULL
}; };
static const char *bad_ata100_5[] = { static const char * const bad_ata100_5[] = {
"IBM-DTLA-307075", "IBM-DTLA-307075",
"IBM-DTLA-307060", "IBM-DTLA-307060",
"IBM-DTLA-307045", "IBM-DTLA-307045",
...@@ -301,6 +307,22 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask) ...@@ -301,6 +307,22 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
return mask; return mask;
} }
/**
* hpt372_filter - mode selection filter
* @adev: ATA device
* @mask: mode mask
*
* 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 hpt372_filter(struct ata_device *adev, unsigned long mask)
{
if (ata_id_is_sata(adev->id))
mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA);
return mask;
}
/** /**
* hpt37x_cable_detect - Detect the cable type * hpt37x_cable_detect - Detect the cable type
* @ap: ATA port to detect on * @ap: ATA port to detect on
...@@ -373,6 +395,7 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline) ...@@ -373,6 +395,7 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
{ 0x50, 1, 0x04, 0x04 }, { 0x50, 1, 0x04, 0x04 },
{ 0x54, 1, 0x04, 0x04 } { 0x54, 1, 0x04, 0x04 }
}; };
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
return -ENOENT; return -ENOENT;
...@@ -586,11 +609,11 @@ static struct ata_port_operations hpt370a_port_ops = { ...@@ -586,11 +609,11 @@ static struct ata_port_operations hpt370a_port_ops = {
}; };
/* /*
* Configuration for HPT372, HPT371, HPT302. Slightly different PIO * Configuration for HPT371 and HPT302. Slightly different PIO and DMA
* and DMA mode setting functionality. * mode setting functionality.
*/ */
static struct ata_port_operations hpt372_port_ops = { static struct ata_port_operations hpt302_port_ops = {
.inherits = &ata_bmdma_port_ops, .inherits = &ata_bmdma_port_ops,
.bmdma_stop = hpt37x_bmdma_stop, .bmdma_stop = hpt37x_bmdma_stop,
...@@ -602,7 +625,17 @@ static struct ata_port_operations hpt372_port_ops = { ...@@ -602,7 +625,17 @@ static struct ata_port_operations hpt372_port_ops = {
}; };
/* /*
* Configuration for HPT374. Mode setting works like 372 and friends * Configuration for HPT372. Mode setting works like 371 and 302
* but we have a mode filter.
*/
static struct ata_port_operations hpt372_port_ops = {
.inherits = &hpt302_port_ops,
.mode_filter = hpt372_filter,
};
/*
* Configuration for HPT374. Mode setting and filtering works like 372
* but we have a different cable detection procedure for function 1. * but we have a different cable detection procedure for function 1.
*/ */
...@@ -647,12 +680,12 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev) ...@@ -647,12 +680,12 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev)
u32 reg5c; u32 reg5c;
int tries; int tries;
for(tries = 0; tries < 0x5000; tries++) { for (tries = 0; tries < 0x5000; tries++) {
udelay(50); udelay(50);
pci_read_config_byte(dev, 0x5b, &reg5b); pci_read_config_byte(dev, 0x5b, &reg5b);
if (reg5b & 0x80) { if (reg5b & 0x80) {
/* See if it stays set */ /* See if it stays set */
for(tries = 0; tries < 0x1000; tries ++) { for (tries = 0; tries < 0x1000; tries++) {
pci_read_config_byte(dev, 0x5b, &reg5b); pci_read_config_byte(dev, 0x5b, &reg5b);
/* Failed ? */ /* Failed ? */
if ((reg5b & 0x80) == 0) if ((reg5b & 0x80) == 0)
...@@ -660,7 +693,7 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev) ...@@ -660,7 +693,7 @@ static int hpt37x_calibrate_dpll(struct pci_dev *dev)
} }
/* Turn off tuning, we have the DPLL set */ /* Turn off tuning, we have the DPLL set */
pci_read_config_dword(dev, 0x5c, &reg5c); pci_read_config_dword(dev, 0x5c, &reg5c);
pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); pci_write_config_dword(dev, 0x5c, reg5c & ~0x100);
return 1; return 1;
} }
} }
...@@ -672,6 +705,7 @@ static u32 hpt374_read_freq(struct pci_dev *pdev) ...@@ -672,6 +705,7 @@ static u32 hpt374_read_freq(struct pci_dev *pdev)
{ {
u32 freq; u32 freq;
unsigned long io_base = pci_resource_start(pdev, 4); unsigned long io_base = pci_resource_start(pdev, 4);
if (PCI_FUNC(pdev->devfn) & 1) { if (PCI_FUNC(pdev->devfn) & 1) {
struct pci_dev *pdev_0; struct pci_dev *pdev_0;
...@@ -737,23 +771,23 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -737,23 +771,23 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA5, .udma_mask = ATA_UDMA5,
.port_ops = &hpt370a_port_ops .port_ops = &hpt370a_port_ops
}; };
/* HPT370 - UDMA100 */ /* HPT370 - UDMA66 */
static const struct ata_port_info info_hpt370_33 = { static const struct ata_port_info info_hpt370_33 = {
.flags = ATA_FLAG_SLAVE_POSS, .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2, .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5, .udma_mask = ATA_UDMA4,
.port_ops = &hpt370_port_ops .port_ops = &hpt370_port_ops
}; };
/* HPT370A - UDMA100 */ /* HPT370A - UDMA66 */
static const struct ata_port_info info_hpt370a_33 = { static const struct ata_port_info info_hpt370a_33 = {
.flags = ATA_FLAG_SLAVE_POSS, .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2, .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5, .udma_mask = ATA_UDMA4,
.port_ops = &hpt370a_port_ops .port_ops = &hpt370a_port_ops
}; };
/* HPT371, 372 and friends - UDMA133 */ /* HPT372 - UDMA133 */
static const struct ata_port_info info_hpt372 = { static const struct ata_port_info info_hpt372 = {
.flags = ATA_FLAG_SLAVE_POSS, .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
...@@ -761,6 +795,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -761,6 +795,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
.port_ops = &hpt372_port_ops .port_ops = &hpt372_port_ops
}; };
/* HPT371, 302 - UDMA133 */
static const struct ata_port_info info_hpt302 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt302_port_ops
};
/* HPT374 - UDMA100, function 1 uses different prereset method */ /* HPT374 - UDMA100, function 1 uses different prereset method */
static const struct ata_port_info info_hpt374_fn0 = { static const struct ata_port_info info_hpt374_fn0 = {
.flags = ATA_FLAG_SLAVE_POSS, .flags = ATA_FLAG_SLAVE_POSS,
...@@ -805,7 +847,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -805,7 +847,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (rev == 6) if (rev == 6)
return -ENODEV; return -ENODEV;
switch(rev) { switch (rev) {
case 3: case 3:
ppi[0] = &info_hpt370; ppi[0] = &info_hpt370;
chip_table = &hpt370; chip_table = &hpt370;
...@@ -821,14 +863,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -821,14 +863,14 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
chip_table = &hpt372; chip_table = &hpt372;
break; break;
default: default:
printk(KERN_ERR "pata_hpt37x: Unknown HPT366 " printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype, "
"subtype, please report (%d).\n", rev); "please report (%d).\n", rev);
return -ENODEV; return -ENODEV;
} }
} else { } else {
switch(dev->device) { switch (dev->device) {
case PCI_DEVICE_ID_TTI_HPT372: case PCI_DEVICE_ID_TTI_HPT372:
/* 372N if rev >= 2*/ /* 372N if rev >= 2 */
if (rev >= 2) if (rev >= 2)
return -ENODEV; return -ENODEV;
ppi[0] = &info_hpt372; ppi[0] = &info_hpt372;
...@@ -838,18 +880,20 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -838,18 +880,20 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* 302N if rev > 1 */ /* 302N if rev > 1 */
if (rev > 1) if (rev > 1)
return -ENODEV; return -ENODEV;
ppi[0] = &info_hpt372; ppi[0] = &info_hpt302;
/* Check this */ /* Check this */
chip_table = &hpt302; chip_table = &hpt302;
break; break;
case PCI_DEVICE_ID_TTI_HPT371: case PCI_DEVICE_ID_TTI_HPT371:
if (rev > 1) if (rev > 1)
return -ENODEV; return -ENODEV;
ppi[0] = &info_hpt372; ppi[0] = &info_hpt302;
chip_table = &hpt371; chip_table = &hpt371;
/* Single channel device, master is not present /*
but the BIOS (or us for non x86) must mark it * Single channel device, master is not present
absent */ * but the BIOS (or us for non x86) must mark it
* absent
*/
pci_read_config_byte(dev, 0x50, &mcr1); pci_read_config_byte(dev, 0x50, &mcr1);
mcr1 &= ~0x04; mcr1 &= ~0x04;
pci_write_config_byte(dev, 0x50, mcr1); pci_write_config_byte(dev, 0x50, mcr1);
...@@ -862,7 +906,9 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -862,7 +906,9 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
*ppi = &info_hpt374_fn1; *ppi = &info_hpt374_fn1;
break; break;
default: default:
printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device); printk(KERN_ERR
"pata_hpt37x: PCI table is bogus, please report (%d).\n",
dev->device);
return -ENODEV; return -ENODEV;
} }
} }
...@@ -893,9 +939,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -893,9 +939,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (chip_table == &hpt372a) if (chip_table == &hpt372a)
outb(0x0e, iobase + 0x9c); outb(0x0e, iobase + 0x9c);
/* Some devices do not let this value be accessed via PCI space /*
according to the old driver. In addition we must use the value * Some devices do not let this value be accessed via PCI space
from FN 0 on the HPT374 */ * according to the old driver. In addition we must use the value
* from FN 0 on the HPT374.
*/
if (chip_table == &hpt374) { if (chip_table == &hpt374) {
freq = hpt374_read_freq(dev); freq = hpt374_read_freq(dev);
...@@ -909,10 +957,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -909,10 +957,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
u8 sr; u8 sr;
u32 total = 0; u32 total = 0;
printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n"); printk(KERN_WARNING
"pata_hpt37x: BIOS has not set timing clocks.\n");
/* This is the process the HPT371 BIOS is reported to use */ /* This is the process the HPT371 BIOS is reported to use */
for(i = 0; i < 128; i++) { for (i = 0; i < 128; i++) {
pci_read_config_byte(dev, 0x78, &sr); pci_read_config_byte(dev, 0x78, &sr);
total += sr & 0x1FF; total += sr & 0x1FF;
udelay(15); udelay(15);
...@@ -947,17 +996,22 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -947,17 +996,22 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* Select the DPLL clock. */ /* Select the DPLL clock. */
pci_write_config_byte(dev, 0x5b, 0x21); pci_write_config_byte(dev, 0x5b, 0x21);
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); pci_write_config_dword(dev, 0x5C,
(f_high << 16) | f_low | 0x100);
for(adjust = 0; adjust < 8; adjust++) { for (adjust = 0; adjust < 8; adjust++) {
if (hpt37x_calibrate_dpll(dev)) if (hpt37x_calibrate_dpll(dev))
break; break;
/* See if it'll settle at a fractionally different clock */ /*
* See if it'll settle at a fractionally
* different clock
*/
if (adjust & 1) if (adjust & 1)
f_low -= adjust >> 1; f_low -= adjust >> 1;
else else
f_high += adjust >> 1; f_high += adjust >> 1;
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); pci_write_config_dword(dev, 0x5C,
(f_high << 16) | f_low | 0x100);
} }
if (adjust == 8) { if (adjust == 8) {
printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n"); printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n");
......
/* /*
* 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: * This driver is heavily based upon:
* *
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc * Portions Copyright (C) 2003 Red Hat Inc
* Portions Copyright (C) 2005-2009 MontaVista Software, Inc. * Portions Copyright (C) 2005-2010 MontaVista Software, Inc.
* *
* *
* TODO * TODO
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "pata_hpt3x2n" #define DRV_NAME "pata_hpt3x2n"
#define DRV_VERSION "0.3.10" #define DRV_VERSION "0.3.13"
enum { enum {
HPT_PCI_FAST = (1 << 31), HPT_PCI_FAST = (1 << 31),
...@@ -103,7 +103,7 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) ...@@ -103,7 +103,7 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed)
{ {
struct hpt_clock *clocks = hpt3x2n_clocks; struct hpt_clock *clocks = hpt3x2n_clocks;
while(clocks->xfer_speed) { while (clocks->xfer_speed) {
if (clocks->xfer_speed == speed) if (clocks->xfer_speed == speed)
return clocks->timing; return clocks->timing;
clocks++; clocks++;
...@@ -112,6 +112,22 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed) ...@@ -112,6 +112,22 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed)
return 0xffffffffU; /* silence compiler warning */ return 0xffffffffU; /* silence compiler warning */
} }
/**
* hpt372n_filter - mode selection filter
* @adev: ATA device
* @mask: mode mask
*
* 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);
return mask;
}
/** /**
* hpt3x2n_cable_detect - Detect the cable type * hpt3x2n_cable_detect - Detect the cable type
* @ap: ATA port to detect on * @ap: ATA port to detect on
...@@ -153,6 +169,7 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline) ...@@ -153,6 +169,7 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline)
{ {
struct ata_port *ap = link->ap; struct ata_port *ap = link->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct pci_dev *pdev = to_pci_dev(ap->host->dev);
/* Reset the state machine */ /* Reset the state machine */
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100); udelay(100);
...@@ -328,10 +345,10 @@ static struct scsi_host_template hpt3x2n_sht = { ...@@ -328,10 +345,10 @@ static struct scsi_host_template hpt3x2n_sht = {
}; };
/* /*
* Configuration for HPT3x2n. * Configuration for HPT302N/371N.
*/ */
static struct ata_port_operations hpt3x2n_port_ops = { static struct ata_port_operations hpt3xxn_port_ops = {
.inherits = &ata_bmdma_port_ops, .inherits = &ata_bmdma_port_ops,
.bmdma_stop = hpt3x2n_bmdma_stop, .bmdma_stop = hpt3x2n_bmdma_stop,
...@@ -345,6 +362,15 @@ static struct ata_port_operations hpt3x2n_port_ops = { ...@@ -345,6 +362,15 @@ static struct ata_port_operations hpt3x2n_port_ops = {
.prereset = hpt3x2n_pre_reset, .prereset = hpt3x2n_pre_reset,
}; };
/*
* 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,
};
/** /**
* hpt3xn_calibrate_dpll - Calibrate the DPLL loop * hpt3xn_calibrate_dpll - Calibrate the DPLL loop
* @dev: PCI device * @dev: PCI device
...@@ -359,12 +385,12 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev) ...@@ -359,12 +385,12 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev)
u32 reg5c; u32 reg5c;
int tries; int tries;
for(tries = 0; tries < 0x5000; tries++) { for (tries = 0; tries < 0x5000; tries++) {
udelay(50); udelay(50);
pci_read_config_byte(dev, 0x5b, &reg5b); pci_read_config_byte(dev, 0x5b, &reg5b);
if (reg5b & 0x80) { if (reg5b & 0x80) {
/* See if it stays set */ /* See if it stays set */
for(tries = 0; tries < 0x1000; tries ++) { for (tries = 0; tries < 0x1000; tries++) {
pci_read_config_byte(dev, 0x5b, &reg5b); pci_read_config_byte(dev, 0x5b, &reg5b);
/* Failed ? */ /* Failed ? */
if ((reg5b & 0x80) == 0) if ((reg5b & 0x80) == 0)
...@@ -372,7 +398,7 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev) ...@@ -372,7 +398,7 @@ static int hpt3xn_calibrate_dpll(struct pci_dev *dev)
} }
/* Turn off tuning, we have the DPLL set */ /* Turn off tuning, we have the DPLL set */
pci_read_config_dword(dev, 0x5c, &reg5c); pci_read_config_dword(dev, 0x5c, &reg5c);
pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100); pci_write_config_dword(dev, 0x5c, reg5c & ~0x100);
return 1; return 1;
} }
} }
...@@ -388,8 +414,19 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) ...@@ -388,8 +414,19 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */ fcnt = inl(iobase + 0x90); /* Not PCI readable for some chips */
if ((fcnt >> 12) != 0xABCDE) { if ((fcnt >> 12) != 0xABCDE) {
printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n"); int i;
return 33; /* Not BIOS set */ u16 sr;
u32 total = 0;
printk(KERN_WARNING "pata_hpt3x2n: 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; fcnt &= 0x1FF;
...@@ -431,21 +468,27 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev) ...@@ -431,21 +468,27 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
* HPT372N 9 (HPT372N) * UDMA133 * HPT372N 9 (HPT372N) * UDMA133
* *
* (1) UDMA133 support depends on the bus clock * (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) static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{ {
/* HPT372N and friends - UDMA133 */ /* HPT372N - UDMA133 */
static const struct ata_port_info info = { 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
};
/* HPT302N and HPT371N - UDMA133 */
static const struct ata_port_info info_hpt3xxn = {
.flags = ATA_FLAG_SLAVE_POSS, .flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2, .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6, .udma_mask = ATA_UDMA6,
.port_ops = &hpt3x2n_port_ops .port_ops = &hpt3xxn_port_ops
}; };
const struct ata_port_info *ppi[] = { &info, NULL }; const struct ata_port_info *ppi[] = { &info_hpt3xxn, NULL };
u8 rev = dev->revision; u8 rev = dev->revision;
u8 irqmask; u8 irqmask;
unsigned int pci_mhz; unsigned int pci_mhz;
...@@ -459,29 +502,35 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -459,29 +502,35 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (rc) if (rc)
return rc; return rc;
switch(dev->device) { switch (dev->device) {
case PCI_DEVICE_ID_TTI_HPT366: case PCI_DEVICE_ID_TTI_HPT366:
/* 372N if rev >= 6 */
if (rev < 6) if (rev < 6)
return -ENODEV; return -ENODEV;
break; goto hpt372n;
case PCI_DEVICE_ID_TTI_HPT371: case PCI_DEVICE_ID_TTI_HPT371:
/* 371N if rev >= 2 */
if (rev < 2) if (rev < 2)
return -ENODEV; return -ENODEV;
/* 371N if rev > 1 */
break; break;
case PCI_DEVICE_ID_TTI_HPT372: case PCI_DEVICE_ID_TTI_HPT372:
/* 372N if rev >= 2*/ /* 372N if rev >= 2 */
if (rev < 2) if (rev < 2)
return -ENODEV; return -ENODEV;
break; goto hpt372n;
case PCI_DEVICE_ID_TTI_HPT302: case PCI_DEVICE_ID_TTI_HPT302:
/* 302N if rev >= 2 */
if (rev < 2) if (rev < 2)
return -ENODEV; return -ENODEV;
break; break;
case PCI_DEVICE_ID_TTI_HPT372N: case PCI_DEVICE_ID_TTI_HPT372N:
hpt372n:
ppi[0] = &info_hpt372n;
break; break;
default: default:
printk(KERN_ERR "pata_hpt3x2n: PCI table is bogus please report (%d).\n", dev->device); printk(KERN_ERR
"pata_hpt3x2n: PCI table is bogus please report (%d).\n",
dev->device);
return -ENODEV; return -ENODEV;
} }
...@@ -509,8 +558,10 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -509,8 +558,10 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
pci_write_config_byte(dev, 0x50, mcr1); 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 */ * 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); pci_mhz = hpt3x2n_pci_clock(dev);
...@@ -522,7 +573,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -522,7 +573,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
pci_write_config_byte(dev, 0x5B, 0x21); pci_write_config_byte(dev, 0x5B, 0x21);
/* Unlike the 37x we don't try jiggling the frequency */ /* 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)) if (hpt3xn_calibrate_dpll(dev))
break; break;
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
...@@ -534,8 +585,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -534,8 +585,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n", printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n",
pci_mhz); pci_mhz);
/* Set our private data up. We only need a few flags so we use
it directly */ /*
* Set our private data up. We only need a few flags
* so we use it directly.
*/
if (pci_mhz > 60) if (pci_mhz > 60)
hpriv = (void *)(PCI66 | USE_DPLL); hpriv = (void *)(PCI66 | USE_DPLL);
...@@ -579,7 +633,7 @@ static void __exit hpt3x2n_exit(void) ...@@ -579,7 +633,7 @@ static void __exit hpt3x2n_exit(void)
} }
MODULE_AUTHOR("Alan Cox"); 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_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, hpt3x2n); MODULE_DEVICE_TABLE(pci, hpt3x2n);
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
......
...@@ -5748,7 +5748,7 @@ static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd, ...@@ -5748,7 +5748,7 @@ static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd,
} }
if (ipr_is_gata(res) && res->sata_port) if (ipr_is_gata(res) && res->sata_port)
return ata_sas_queuecmd(scsi_cmd, done, res->sata_port->ap); return ata_sas_queuecmd(scsi_cmd, res->sata_port->ap);
ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
ioarcb = &ipr_cmd->ioarcb; ioarcb = &ipr_cmd->ioarcb;
......
...@@ -211,8 +211,7 @@ static int sas_queuecommand_lck(struct scsi_cmnd *cmd, ...@@ -211,8 +211,7 @@ static int sas_queuecommand_lck(struct scsi_cmnd *cmd,
unsigned long flags; unsigned long flags;
spin_lock_irqsave(dev->sata_dev.ap->lock, flags); spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
res = ata_sas_queuecmd(cmd, scsi_done, res = ata_sas_queuecmd(cmd, dev->sata_dev.ap);
dev->sata_dev.ap);
spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags); spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
goto out; goto out;
} }
......
...@@ -996,8 +996,7 @@ extern int ata_sas_port_init(struct ata_port *); ...@@ -996,8 +996,7 @@ extern int ata_sas_port_init(struct ata_port *);
extern int ata_sas_port_start(struct ata_port *ap); extern int ata_sas_port_start(struct ata_port *ap);
extern void ata_sas_port_stop(struct ata_port *ap); extern void ata_sas_port_stop(struct ata_port *ap);
extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *); extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *);
extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap);
struct ata_port *ap);
extern int sata_scr_valid(struct ata_link *link); extern int sata_scr_valid(struct ata_link *link);
extern int sata_scr_read(struct ata_link *link, int reg, u32 *val); extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
extern int sata_scr_write(struct ata_link *link, int reg, u32 val); extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
...@@ -1040,8 +1039,7 @@ extern unsigned int ata_do_dev_read_id(struct ata_device *dev, ...@@ -1040,8 +1039,7 @@ extern unsigned int ata_do_dev_read_id(struct ata_device *dev,
struct ata_taskfile *tf, u16 *id); struct ata_taskfile *tf, u16 *id);
extern void ata_qc_complete(struct ata_queued_cmd *qc); extern void ata_qc_complete(struct ata_queued_cmd *qc);
extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active); extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active);
extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd);
void (*done)(struct scsi_cmnd *));
extern int ata_std_bios_param(struct scsi_device *sdev, extern int ata_std_bios_param(struct scsi_device *sdev,
struct block_device *bdev, struct block_device *bdev,
sector_t capacity, int geom[]); sector_t capacity, int geom[]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment