pata_pdc2027x: Updates
Signed-off-by: Alan Cox <alan@redhat.com> Correct missing modefilter (crash if BAR4 unassigned) Use Cable Detect method Wrap ->set_mode instead ready for ->post_set_mode removal Maxtor errata as per Jeff Garzik report Remove duplicated private udma_mask hacking Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
@@ -35,7 +35,7 @@
|
|||||||
#include <linux/libata.h>
|
#include <linux/libata.h>
|
||||||
|
|
||||||
#define DRV_NAME "pata_pdc2027x"
|
#define DRV_NAME "pata_pdc2027x"
|
||||||
#define DRV_VERSION "0.8"
|
#define DRV_VERSION "0.9"
|
||||||
#undef PDC_DEBUG
|
#undef PDC_DEBUG
|
||||||
|
|
||||||
#ifdef PDC_DEBUG
|
#ifdef PDC_DEBUG
|
||||||
@@ -66,8 +66,10 @@ static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *e
|
|||||||
static void pdc2027x_error_handler(struct ata_port *ap);
|
static void pdc2027x_error_handler(struct ata_port *ap);
|
||||||
static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev);
|
static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev);
|
||||||
static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);
|
static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);
|
||||||
static void pdc2027x_post_set_mode(struct ata_port *ap);
|
|
||||||
static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc);
|
static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc);
|
||||||
|
static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask);
|
||||||
|
static int pdc2027x_cable_detect(struct ata_port *ap);
|
||||||
|
static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ATA Timing Tables based on 133MHz controller clock.
|
* ATA Timing Tables based on 133MHz controller clock.
|
||||||
@@ -146,6 +148,7 @@ static struct scsi_host_template pdc2027x_sht = {
|
|||||||
|
|
||||||
static struct ata_port_operations pdc2027x_pata100_ops = {
|
static struct ata_port_operations pdc2027x_pata100_ops = {
|
||||||
.port_disable = ata_port_disable,
|
.port_disable = ata_port_disable,
|
||||||
|
.mode_filter = ata_pci_default_filter,
|
||||||
|
|
||||||
.tf_load = ata_tf_load,
|
.tf_load = ata_tf_load,
|
||||||
.tf_read = ata_tf_read,
|
.tf_read = ata_tf_read,
|
||||||
@@ -166,6 +169,7 @@ static struct ata_port_operations pdc2027x_pata100_ops = {
|
|||||||
.thaw = ata_bmdma_thaw,
|
.thaw = ata_bmdma_thaw,
|
||||||
.error_handler = pdc2027x_error_handler,
|
.error_handler = pdc2027x_error_handler,
|
||||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||||
|
.cable_detect = pdc2027x_cable_detect,
|
||||||
|
|
||||||
.irq_handler = ata_interrupt,
|
.irq_handler = ata_interrupt,
|
||||||
.irq_clear = ata_bmdma_irq_clear,
|
.irq_clear = ata_bmdma_irq_clear,
|
||||||
@@ -179,7 +183,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
|
|||||||
.port_disable = ata_port_disable,
|
.port_disable = ata_port_disable,
|
||||||
.set_piomode = pdc2027x_set_piomode,
|
.set_piomode = pdc2027x_set_piomode,
|
||||||
.set_dmamode = pdc2027x_set_dmamode,
|
.set_dmamode = pdc2027x_set_dmamode,
|
||||||
.post_set_mode = pdc2027x_post_set_mode,
|
.set_mode = pdc2027x_set_mode,
|
||||||
|
.mode_filter = pdc2027x_mode_filter,
|
||||||
|
|
||||||
.tf_load = ata_tf_load,
|
.tf_load = ata_tf_load,
|
||||||
.tf_read = ata_tf_read,
|
.tf_read = ata_tf_read,
|
||||||
@@ -200,6 +205,7 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
|
|||||||
.thaw = ata_bmdma_thaw,
|
.thaw = ata_bmdma_thaw,
|
||||||
.error_handler = pdc2027x_error_handler,
|
.error_handler = pdc2027x_error_handler,
|
||||||
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
.post_internal_cmd = ata_bmdma_post_internal_cmd,
|
||||||
|
.cable_detect = pdc2027x_cable_detect,
|
||||||
|
|
||||||
.irq_handler = ata_interrupt,
|
.irq_handler = ata_interrupt,
|
||||||
.irq_clear = ata_bmdma_irq_clear,
|
.irq_clear = ata_bmdma_irq_clear,
|
||||||
@@ -261,7 +267,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pdc2027x_pata_cbl_detect - Probe host controller cable detect info
|
* pdc2027x_pata_cable_detect - Probe host controller cable detect info
|
||||||
* @ap: Port for which cable detect info is desired
|
* @ap: Port for which cable detect info is desired
|
||||||
*
|
*
|
||||||
* Read 80c cable indicator from Promise extended register.
|
* Read 80c cable indicator from Promise extended register.
|
||||||
@@ -270,7 +276,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
|
|||||||
* LOCKING:
|
* LOCKING:
|
||||||
* None (inherited from caller).
|
* None (inherited from caller).
|
||||||
*/
|
*/
|
||||||
static void pdc2027x_cbl_detect(struct ata_port *ap)
|
static int pdc2027x_cable_detect(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
u32 cgcr;
|
u32 cgcr;
|
||||||
|
|
||||||
@@ -281,13 +287,10 @@ static void pdc2027x_cbl_detect(struct ata_port *ap)
|
|||||||
|
|
||||||
PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no);
|
PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no);
|
||||||
|
|
||||||
ap->cbl = ATA_CBL_PATA80;
|
return ATA_CBL_PATA80;
|
||||||
return;
|
|
||||||
|
|
||||||
cbl40:
|
cbl40:
|
||||||
printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no);
|
printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no);
|
||||||
ap->cbl = ATA_CBL_PATA40;
|
return ATA_CBL_PATA40;
|
||||||
ap->udma_mask &= ATA_UDMA_MASK_40C;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -314,7 +317,6 @@ static int pdc2027x_prereset(struct ata_port *ap)
|
|||||||
/* Check whether port enabled */
|
/* Check whether port enabled */
|
||||||
if (!pdc2027x_port_enabled(ap))
|
if (!pdc2027x_port_enabled(ap))
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
pdc2027x_cbl_detect(ap);
|
|
||||||
return ata_std_prereset(ap);
|
return ata_std_prereset(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,6 +335,32 @@ static void pdc2027x_error_handler(struct ata_port *ap)
|
|||||||
ata_bmdma_drive_eh(ap, pdc2027x_prereset, ata_std_softreset, NULL, ata_std_postreset);
|
ata_bmdma_drive_eh(ap, pdc2027x_prereset, ata_std_softreset, NULL, ata_std_postreset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pdc2720x_mode_filter - mode selection filter
|
||||||
|
* @adev: ATA device
|
||||||
|
* @mask: list of modes proposed
|
||||||
|
*
|
||||||
|
* Block UDMA on devices that cause trouble with this controller.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask)
|
||||||
|
{
|
||||||
|
unsigned char model_num[ATA_ID_PROD_LEN + 1];
|
||||||
|
struct ata_device *pair = ata_dev_pair(adev);
|
||||||
|
|
||||||
|
if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL)
|
||||||
|
return ata_pci_default_filter(adev, mask);
|
||||||
|
|
||||||
|
/* Check for slave of a Maxtor at UDMA6 */
|
||||||
|
ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
|
||||||
|
ATA_ID_PROD_LEN + 1);
|
||||||
|
/* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */
|
||||||
|
if(strstr(model_num, "Maxtor") == 0 && pair->dma_mode == XFER_UDMA_6)
|
||||||
|
mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
|
||||||
|
|
||||||
|
return ata_pci_default_filter(adev, mask);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pdc2027x_set_piomode - Initialize host controller PATA PIO timings
|
* pdc2027x_set_piomode - Initialize host controller PATA PIO timings
|
||||||
* @ap: Port to configure
|
* @ap: Port to configure
|
||||||
@@ -444,17 +472,22 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pdc2027x_post_set_mode - Set the timing registers back to correct values.
|
* pdc2027x_set_mode - Set the timing registers back to correct values.
|
||||||
* @ap: Port to configure
|
* @ap: Port to configure
|
||||||
|
* @r_failed: Returned device for failure
|
||||||
*
|
*
|
||||||
* The pdc2027x hardware will look at "SET FEATURES" and change the timing registers
|
* The pdc2027x hardware will look at "SET FEATURES" and change the timing registers
|
||||||
* automatically. The values set by the hardware might be incorrect, under 133Mhz PLL.
|
* automatically. The values set by the hardware might be incorrect, under 133Mhz PLL.
|
||||||
* This function overwrites the possibly incorrect values set by the hardware to be correct.
|
* This function overwrites the possibly incorrect values set by the hardware to be correct.
|
||||||
*/
|
*/
|
||||||
static void pdc2027x_post_set_mode(struct ata_port *ap)
|
static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
i = ata_do_set_mode(ap, r_failed);
|
||||||
|
if (i < 0)
|
||||||
|
return i;
|
||||||
|
|
||||||
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
for (i = 0; i < ATA_MAX_DEVICES; i++) {
|
||||||
struct ata_device *dev = &ap->device[i];
|
struct ata_device *dev = &ap->device[i];
|
||||||
|
|
||||||
@@ -476,6 +509,7 @@ static void pdc2027x_post_set_mode(struct ata_port *ap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user