mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-12 00:00:00 +00:00
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:
parent
0dcd0a7637
commit
8c7e8f947f
@ -79,15 +79,6 @@ static int all;
|
|||||||
module_param(all, int, 0444);
|
module_param(all, int, 0444);
|
||||||
MODULE_PARM_DESC(all, "Grab all legacy port devices, even if PCI(0=off, 1=on)");
|
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 {
|
enum controller {
|
||||||
BIOS = 0,
|
BIOS = 0,
|
||||||
SNOOP = 1,
|
SNOOP = 1,
|
||||||
@ -104,6 +95,14 @@ enum controller {
|
|||||||
UNKNOWN = -1
|
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 {
|
struct legacy_probe {
|
||||||
unsigned char *name;
|
unsigned char *name;
|
||||||
@ -637,77 +636,20 @@ static struct ata_port_operations opti82c46x_port_ops = {
|
|||||||
.qc_issue = opti82c46x_qc_issue,
|
.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
|
* qdi65x0_set_piomode - PIO setup for QDI65x0
|
||||||
* @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
|
|
||||||
* @ap: Port
|
* @ap: Port
|
||||||
* @adev: Device
|
* @adev: Device
|
||||||
*
|
*
|
||||||
* In single channel mode the 6580 has one clock per device and we can
|
* 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
|
* 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.
|
* 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 ata_timing t;
|
||||||
struct legacy_data *ld_qdi = ap->host->private_data;
|
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;
|
timing = (recovery << 4) | active | 0x08;
|
||||||
ld_qdi->clock[adev->devno] = timing;
|
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 */
|
/* 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);
|
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 = {
|
static struct ata_port_operations qdi6500_port_ops = {
|
||||||
.inherits = &legacy_base_port_ops,
|
.inherits = &legacy_base_port_ops,
|
||||||
.set_piomode = qdi6500_set_piomode,
|
.set_piomode = qdi65x0_set_piomode,
|
||||||
.qc_issue = qdi_qc_issue,
|
.qc_issue = qdi_qc_issue,
|
||||||
.sff_data_xfer = vlb32_data_xfer,
|
.sff_data_xfer = vlb32_data_xfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ata_port_operations qdi6580_port_ops = {
|
static struct ata_port_operations qdi6580_port_ops = {
|
||||||
.inherits = &legacy_base_port_ops,
|
.inherits = &legacy_base_port_ops,
|
||||||
.set_piomode = qdi6580_set_piomode,
|
.set_piomode = qdi65x0_set_piomode,
|
||||||
.sff_data_xfer = vlb32_data_xfer,
|
.sff_data_xfer = vlb32_data_xfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ata_port_operations qdi6580dp_port_ops = {
|
static struct ata_port_operations qdi6580dp_port_ops = {
|
||||||
.inherits = &legacy_base_port_ops,
|
.inherits = &legacy_base_port_ops,
|
||||||
.set_piomode = qdi6580dp_set_piomode,
|
.set_piomode = qdi65x0_set_piomode,
|
||||||
.qc_issue = qdi_qc_issue,
|
.qc_issue = qdi_qc_issue,
|
||||||
.sff_data_xfer = vlb32_data_xfer,
|
.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);
|
ctrl_addr = devm_ioport_map(&pdev->dev, io + 0x0206, 1);
|
||||||
if (!io_addr || !ctrl_addr)
|
if (!io_addr || !ctrl_addr)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
ld->type = probe->type;
|
||||||
if (controller->setup)
|
if (controller->setup)
|
||||||
if (controller->setup(pdev, probe, ld) < 0)
|
if (controller->setup(pdev, probe, ld) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user