pata_legacy: unify QDI ->set_piomode methods

Add controller type field to struct legacy_data and then use it
to merge together all ->set_piomode methods for QDI controllers.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
Bartlomiej Zolnierkiewicz 2011-10-13 15:06:56 +02:00 committed by Jeff Garzik
parent 0dcd0a7637
commit 8c7e8f947f
1 changed files with 24 additions and 76 deletions

View File

@ -79,15 +79,6 @@ static int all;
module_param(all, int, 0444);
MODULE_PARM_DESC(all, "Grab all legacy port devices, even if PCI(0=off, 1=on)");
struct legacy_data {
unsigned long timing;
u8 clock[2];
u8 last;
int fast;
struct platform_device *platform_dev;
};
enum controller {
BIOS = 0,
SNOOP = 1,
@ -104,6 +95,14 @@ enum controller {
UNKNOWN = -1
};
struct legacy_data {
unsigned long timing;
u8 clock[2];
u8 last;
int fast;
enum controller type;
struct platform_device *platform_dev;
};
struct legacy_probe {
unsigned char *name;
@ -637,77 +636,20 @@ static struct ata_port_operations opti82c46x_port_ops = {
.qc_issue = opti82c46x_qc_issue,
};
static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (ld_qdi->fast) {
active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - clamp_val(t.recover, 3, 18);
} else {
active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - clamp_val(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
ld_qdi->clock[adev->devno] = timing;
outb(timing, ld_qdi->timing);
}
/**
* qdi6580dp_set_piomode - PIO setup for dual channel
* @ap: Port
* @adev: Device
*
* In dual channel mode the 6580 has one clock per channel and we have
* to software clockswitch in qc_issue.
*/
static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
struct legacy_data *ld_qdi = ap->host->private_data;
int active, recovery;
u8 timing;
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
if (ld_qdi->fast) {
active = 8 - clamp_val(t.active, 1, 8);
recovery = 18 - clamp_val(t.recover, 3, 18);
} else {
active = 9 - clamp_val(t.active, 2, 9);
recovery = 15 - clamp_val(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
ld_qdi->clock[adev->devno] = timing;
outb(timing, ld_qdi->timing + 2 * ap->port_no);
/* Clear the FIFO */
if (adev->class != ATA_DEV_ATA)
outb(0x5F, (ld_qdi->timing & 0xFFF0) + 3);
}
/**
* qdi6580_set_piomode - PIO setup for single channel
* qdi65x0_set_piomode - PIO setup for QDI65x0
* @ap: Port
* @adev: Device
*
* In single channel mode the 6580 has one clock per device and we can
* avoid the requirement to clock switch. We also have to load the timing
* into the right clock according to whether we are master or slave.
*
* In dual channel mode the 6580 has one clock per channel and we have
* to software clockswitch in qc_issue.
*/
static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void qdi65x0_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
struct ata_timing t;
struct legacy_data *ld_qdi = ap->host->private_data;
@ -726,9 +668,14 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
timing = (recovery << 4) | active | 0x08;
ld_qdi->clock[adev->devno] = timing;
outb(timing, ld_qdi->timing + 2 * adev->devno);
if (ld_qdi->type == QDI6580)
outb(timing, ld_qdi->timing + 2 * adev->devno);
else
outb(timing, ld_qdi->timing + 2 * ap->port_no);
/* Clear the FIFO */
if (adev->class != ATA_DEV_ATA)
if (ld_qdi->type != QDI6500 && adev->class != ATA_DEV_ATA)
outb(0x5F, (ld_qdi->timing & 0xFFF0) + 3);
}
@ -795,20 +742,20 @@ static int qdi_port(struct platform_device *dev,
static struct ata_port_operations qdi6500_port_ops = {
.inherits = &legacy_base_port_ops,
.set_piomode = qdi6500_set_piomode,
.set_piomode = qdi65x0_set_piomode,
.qc_issue = qdi_qc_issue,
.sff_data_xfer = vlb32_data_xfer,
};
static struct ata_port_operations qdi6580_port_ops = {
.inherits = &legacy_base_port_ops,
.set_piomode = qdi6580_set_piomode,
.set_piomode = qdi65x0_set_piomode,
.sff_data_xfer = vlb32_data_xfer,
};
static struct ata_port_operations qdi6580dp_port_ops = {
.inherits = &legacy_base_port_ops,
.set_piomode = qdi6580dp_set_piomode,
.set_piomode = qdi65x0_set_piomode,
.qc_issue = qdi_qc_issue,
.sff_data_xfer = vlb32_data_xfer,
};
@ -1028,6 +975,7 @@ static __init int legacy_init_one(struct legacy_probe *probe)
ctrl_addr = devm_ioport_map(&pdev->dev, io + 0x0206, 1);
if (!io_addr || !ctrl_addr)
goto fail;
ld->type = probe->type;
if (controller->setup)
if (controller->setup(pdev, probe, ld) < 0)
goto fail;