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: ahci: sis can't do PMP ata_piix: add TECRA M4 to broken suspend list LIBATA: Add HAVE_PATA_PLATFORM to select PATA_PLATFORM driver sata_mv: warn on PIO with multiple DRQs sata_mv: enable async_notify for 60x1 Rev.C0 and higher libata: don't check whether to use DMA or not for no data commands ahci: jmb361 has only one port
This commit is contained in:
commit
b4eea67a12
|
@ -651,9 +651,17 @@ config PATA_WINBOND_VLB
|
||||||
Support for the Winbond W83759A controller on Vesa Local Bus
|
Support for the Winbond W83759A controller on Vesa Local Bus
|
||||||
systems.
|
systems.
|
||||||
|
|
||||||
|
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 || ARCH_RPC || PPC
|
depends on EMBEDDED || ARCH_RPC || PPC || HAVE_PATA_PLATFORM
|
||||||
help
|
help
|
||||||
This option enables support for generic directly connected ATA
|
This option enables support for generic directly connected ATA
|
||||||
devices commonly found on embedded systems.
|
devices commonly found on embedded systems.
|
||||||
|
|
|
@ -90,6 +90,7 @@ enum {
|
||||||
board_ahci_mv = 4,
|
board_ahci_mv = 4,
|
||||||
board_ahci_sb700 = 5,
|
board_ahci_sb700 = 5,
|
||||||
board_ahci_mcp65 = 6,
|
board_ahci_mcp65 = 6,
|
||||||
|
board_ahci_nopmp = 7,
|
||||||
|
|
||||||
/* global controller registers */
|
/* global controller registers */
|
||||||
HOST_CAP = 0x00, /* host capabilities */
|
HOST_CAP = 0x00, /* host capabilities */
|
||||||
|
@ -401,6 +402,14 @@ static const struct ata_port_info ahci_port_info[] = {
|
||||||
.udma_mask = ATA_UDMA6,
|
.udma_mask = ATA_UDMA6,
|
||||||
.port_ops = &ahci_ops,
|
.port_ops = &ahci_ops,
|
||||||
},
|
},
|
||||||
|
/* board_ahci_nopmp */
|
||||||
|
{
|
||||||
|
AHCI_HFLAGS (AHCI_HFLAG_NO_PMP),
|
||||||
|
.flags = AHCI_FLAG_COMMON,
|
||||||
|
.pio_mask = 0x1f, /* pio0-4 */
|
||||||
|
.udma_mask = ATA_UDMA6,
|
||||||
|
.port_ops = &ahci_ops,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pci_device_id ahci_pci_tbl[] = {
|
static const struct pci_device_id ahci_pci_tbl[] = {
|
||||||
|
@ -525,9 +534,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
||||||
{ PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */
|
{ PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci }, /* MCP7B */
|
||||||
|
|
||||||
/* SiS */
|
/* SiS */
|
||||||
{ PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
|
{ PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp }, /* SiS 966 */
|
||||||
{ PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
|
{ PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp }, /* SiS 968 */
|
||||||
{ PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
|
{ PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp }, /* SiS 968 */
|
||||||
|
|
||||||
/* Marvell */
|
/* Marvell */
|
||||||
{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
|
{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
|
||||||
|
@ -653,6 +662,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
|
||||||
cap &= ~HOST_CAP_PMP;
|
cap &= ~HOST_CAP_PMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 &&
|
||||||
|
port_map != 1) {
|
||||||
|
dev_printk(KERN_INFO, &pdev->dev,
|
||||||
|
"JMB361 has only one port, port_map 0x%x -> 0x%x\n",
|
||||||
|
port_map, 1);
|
||||||
|
port_map = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Temporary Marvell 6145 hack: PATA port presence
|
* Temporary Marvell 6145 hack: PATA port presence
|
||||||
* is asserted through the standard AHCI port
|
* is asserted through the standard AHCI port
|
||||||
|
|
|
@ -1042,6 +1042,13 @@ static int piix_broken_suspend(void)
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Tecra M4"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "Tecra M4"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.ident = "TECRA M4",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M4"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.ident = "TECRA M5",
|
.ident = "TECRA M5",
|
||||||
.matches = {
|
.matches = {
|
||||||
|
|
|
@ -4297,7 +4297,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_check_atapi_dma - Check whether ATAPI DMA can be supported
|
* atapi_check_dma - Check whether ATAPI DMA can be supported
|
||||||
* @qc: Metadata associated with taskfile to check
|
* @qc: Metadata associated with taskfile to check
|
||||||
*
|
*
|
||||||
* Allow low-level driver to filter ATA PACKET commands, returning
|
* Allow low-level driver to filter ATA PACKET commands, returning
|
||||||
|
@ -4310,7 +4310,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
|
||||||
* RETURNS: 0 when ATAPI DMA can be used
|
* RETURNS: 0 when ATAPI DMA can be used
|
||||||
* nonzero otherwise
|
* nonzero otherwise
|
||||||
*/
|
*/
|
||||||
int ata_check_atapi_dma(struct ata_queued_cmd *qc)
|
int atapi_check_dma(struct ata_queued_cmd *qc)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = qc->ap;
|
struct ata_port *ap = qc->ap;
|
||||||
|
|
||||||
|
|
|
@ -2343,8 +2343,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
|
||||||
{
|
{
|
||||||
struct scsi_cmnd *scmd = qc->scsicmd;
|
struct scsi_cmnd *scmd = qc->scsicmd;
|
||||||
struct ata_device *dev = qc->dev;
|
struct ata_device *dev = qc->dev;
|
||||||
int using_pio = (dev->flags & ATA_DFLAG_PIO);
|
|
||||||
int nodata = (scmd->sc_data_direction == DMA_NONE);
|
int nodata = (scmd->sc_data_direction == DMA_NONE);
|
||||||
|
int using_pio = !nodata && (dev->flags & ATA_DFLAG_PIO);
|
||||||
unsigned int nbytes;
|
unsigned int nbytes;
|
||||||
|
|
||||||
memset(qc->cdb, 0, dev->cdb_len);
|
memset(qc->cdb, 0, dev->cdb_len);
|
||||||
|
@ -2362,7 +2362,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
|
||||||
ata_qc_set_pc_nbytes(qc);
|
ata_qc_set_pc_nbytes(qc);
|
||||||
|
|
||||||
/* check whether ATAPI DMA is safe */
|
/* check whether ATAPI DMA is safe */
|
||||||
if (!using_pio && ata_check_atapi_dma(qc))
|
if (!nodata && !using_pio && atapi_check_dma(qc))
|
||||||
using_pio = 1;
|
using_pio = 1;
|
||||||
|
|
||||||
/* Some controller variants snoop this value for Packet
|
/* Some controller variants snoop this value for Packet
|
||||||
|
@ -2402,13 +2402,11 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
|
||||||
qc->tf.lbam = (nbytes & 0xFF);
|
qc->tf.lbam = (nbytes & 0xFF);
|
||||||
qc->tf.lbah = (nbytes >> 8);
|
qc->tf.lbah = (nbytes >> 8);
|
||||||
|
|
||||||
if (using_pio || nodata) {
|
if (nodata)
|
||||||
/* no data, or PIO data xfer */
|
qc->tf.protocol = ATAPI_PROT_NODATA;
|
||||||
if (nodata)
|
else if (using_pio)
|
||||||
qc->tf.protocol = ATAPI_PROT_NODATA;
|
qc->tf.protocol = ATAPI_PROT_PIO;
|
||||||
else
|
else {
|
||||||
qc->tf.protocol = ATAPI_PROT_PIO;
|
|
||||||
} else {
|
|
||||||
/* DMA data xfer */
|
/* DMA data xfer */
|
||||||
qc->tf.protocol = ATAPI_PROT_DMA;
|
qc->tf.protocol = ATAPI_PROT_DMA;
|
||||||
qc->tf.feature |= ATAPI_PKT_DMA;
|
qc->tf.feature |= ATAPI_PKT_DMA;
|
||||||
|
|
|
@ -106,7 +106,7 @@ extern void ata_sg_clean(struct ata_queued_cmd *qc);
|
||||||
extern void ata_qc_free(struct ata_queued_cmd *qc);
|
extern void ata_qc_free(struct ata_queued_cmd *qc);
|
||||||
extern void ata_qc_issue(struct ata_queued_cmd *qc);
|
extern void ata_qc_issue(struct ata_queued_cmd *qc);
|
||||||
extern void __ata_qc_complete(struct ata_queued_cmd *qc);
|
extern void __ata_qc_complete(struct ata_queued_cmd *qc);
|
||||||
extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
|
extern int atapi_check_dma(struct ata_queued_cmd *qc);
|
||||||
extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
|
extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
|
||||||
extern void ata_dev_init(struct ata_device *dev);
|
extern void ata_dev_init(struct ata_device *dev);
|
||||||
extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
|
extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
|
||||||
|
|
|
@ -1322,6 +1322,9 @@ static int mv_port_start(struct ata_port *ap)
|
||||||
goto out_port_free_dma_mem;
|
goto out_port_free_dma_mem;
|
||||||
memset(pp->crpb, 0, MV_CRPB_Q_SZ);
|
memset(pp->crpb, 0, MV_CRPB_Q_SZ);
|
||||||
|
|
||||||
|
/* 6041/6081 Rev. "C0" (and newer) are okay with async notify */
|
||||||
|
if (hpriv->hp_flags & MV_HP_ERRATA_60X1C0)
|
||||||
|
ap->flags |= ATA_FLAG_AN;
|
||||||
/*
|
/*
|
||||||
* For GEN_I, there's no NCQ, so we only allocate a single sg_tbl.
|
* For GEN_I, there's no NCQ, so we only allocate a single sg_tbl.
|
||||||
* For later hardware, we need one unique sg_tbl per NCQ tag.
|
* For later hardware, we need one unique sg_tbl per NCQ tag.
|
||||||
|
@ -1592,6 +1595,24 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
|
||||||
|
|
||||||
if ((qc->tf.protocol != ATA_PROT_DMA) &&
|
if ((qc->tf.protocol != ATA_PROT_DMA) &&
|
||||||
(qc->tf.protocol != ATA_PROT_NCQ)) {
|
(qc->tf.protocol != ATA_PROT_NCQ)) {
|
||||||
|
static int limit_warnings = 10;
|
||||||
|
/*
|
||||||
|
* Errata SATA#16, SATA#24: warn if multiple DRQs expected.
|
||||||
|
*
|
||||||
|
* Someday, we might implement special polling workarounds
|
||||||
|
* for these, but it all seems rather unnecessary since we
|
||||||
|
* normally use only DMA for commands which transfer more
|
||||||
|
* than a single block of data.
|
||||||
|
*
|
||||||
|
* Much of the time, this could just work regardless.
|
||||||
|
* So for now, just log the incident, and allow the attempt.
|
||||||
|
*/
|
||||||
|
if (limit_warnings && (qc->nbytes / qc->sect_size) > 1) {
|
||||||
|
--limit_warnings;
|
||||||
|
ata_link_printk(qc->dev->link, KERN_WARNING, DRV_NAME
|
||||||
|
": attempting PIO w/multiple DRQ: "
|
||||||
|
"this may fail due to h/w errata\n");
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* We're about to send a non-EDMA capable command to the
|
* We're about to send a non-EDMA capable command to the
|
||||||
* port. Turn off EDMA so there won't be problems accessing
|
* port. Turn off EDMA so there won't be problems accessing
|
||||||
|
|
Loading…
Reference in New Issue