u8 last;
int fast;
struct platform_device *platform_dev;
-
+
};
static struct ata_host *qdi_host[NR_HOST];
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
-
+
if (qdi->fast) {
active = 8 - FIT(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18);
recovery = 15 - FIT(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
-
+
qdi->clock[adev->devno] = timing;
- outb(timing, qdi->timing);
+ outb(timing, qdi->timing);
}
static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
-
+
if (qdi->fast) {
active = 8 - FIT(t.active, 1, 8);
recovery = 18 - FIT(t.recover, 3, 18);
recovery = 15 - FIT(t.recover, 0, 15);
}
timing = (recovery << 4) | active | 0x08;
-
+
qdi->clock[adev->devno] = timing;
outb(timing, qdi->timing);
-
+
/* Clear the FIFO */
if (adev->class != ATA_DEV_ATA)
outb(0x5F, (qdi->timing & 0xFFF0) + 3);
{
struct ata_port *ap = adev->ap;
int slop = buflen & 3;
-
+
if (ata_id_has_dword_io(adev->id)) {
if (write_data)
- outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
- insl(ap->ioaddr.data_addr, buf, buflen >> 2);
-
+ ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
+
if (unlikely(slop)) {
u32 pad;
if (write_data) {
memcpy(&pad, buf + buflen - slop, slop);
- outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ pad = le32_to_cpu(pad);
+ iowrite32(pad, ap->ioaddr.data_addr);
} else {
- pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
+ pad = ioread32(ap->ioaddr.data_addr);
+ pad = cpu_to_le32(pad);
memcpy(buf + buflen - slop, &pad, slop);
}
}
} else
- ata_pio_data_xfer(adev, buf, buflen, write_data);
+ ata_data_xfer(adev, buf, buflen, write_data);
}
static struct scsi_host_template qdi_sht = {
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
.proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
};
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
-
+
.qc_prep = ata_qc_prep,
.qc_issue = qdi_qc_issue_prot,
- .eng_timeout = ata_eng_timeout,
+
.data_xfer = qdi_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
-
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
+
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
-};
+};
static struct ata_port_operations qdi6580_port_ops = {
.port_disable = ata_port_disable,
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
-
+
.qc_prep = ata_qc_prep,
.qc_issue = qdi_qc_issue_prot,
- .eng_timeout = ata_eng_timeout,
+
.data_xfer = qdi_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
-
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
+
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
-};
+};
/**
* qdi_init_one - attach a qdi interface
* Register an ISA bus IDE interface. Such interfaces are PIO and we
* assume do not support IRQ sharing.
*/
-
+
static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast)
{
struct ata_probe_ent ae;
struct platform_device *pdev;
+ void __iomem *io_addr, *ctl_addr;
int ret;
- unsigned long ctrl = io + 0x206;
-
/*
* Fill in a probe structure first of all
*/
pdev = platform_device_register_simple(DRV_NAME, nr_qdi_host, NULL, 0);
- if (pdev == NULL)
- return -ENOMEM;
-
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ ret = -ENOMEM;
+ io_addr = devm_ioport_map(&pdev->dev, io, 8);
+ ctl_addr = devm_ioport_map(&pdev->dev, io + 0x206, 1);
+ if (!io_addr || !ctl_addr)
+ goto fail;
+
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
ae.dev = &pdev->dev;
-
+
if (type == 6580) {
ae.port_ops = &qdi6580_port_ops;
ae.pio_mask = 0x1F;
+ ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
} else {
ae.port_ops = &qdi6500_port_ops;
ae.pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */
+ ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
+ ATA_FLAG_NO_IORDY;
}
-
+
ae.sht = &qdi_sht;
ae.n_ports = 1;
ae.irq = irq;
ae.irq_flags = 0;
- ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- ae.port[0].cmd_addr = io;
- ae.port[0].altstatus_addr = ctrl;
- ae.port[0].ctl_addr = ctrl;
+ ae.port[0].cmd_addr = io_addr;
+ ae.port[0].altstatus_addr = ctl_addr;
+ ae.port[0].ctl_addr = ctl_addr;
ata_std_ports(&ae.port[0]);
/*
qdi_data[nr_qdi_host].platform_dev = pdev;
printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io);
- ret = ata_device_add(&ae);
- if (ret == 0) {
- platform_device_unregister(pdev);
- return -ENODEV;
- }
-
+
+ ret = -ENODEV;
+ if (!ata_device_add(&ae))
+ goto fail;
+
qdi_host[nr_qdi_host++] = dev_get_drvdata(&pdev->dev);
- return 0;
+ return 0;
+
+ fail:
+ platform_device_unregister(pdev);
+ return ret;
}
/**
*
* Attach qdi IDE interfaces by scanning the ports it may occupy.
*/
-
+
static __init int qdi_init(void)
{
unsigned long flags;
static const unsigned long qd_port[2] = { 0x30, 0xB0 };
static const unsigned long ide_port[2] = { 0x170, 0x1F0 };
static const int ide_irq[2] = { 14, 15 };
-
+
int ct = 0;
int i;
-
+
if (probe_qdi == 0)
return -ENODEV;
-
+
/*
* Check each possible QD65xx base address
*/
-
+
for (i = 0; i < 2; i++) {
unsigned long port = qd_port[i];
u8 r, res;
-
-
+
+
if (request_region(port, 2, "pata_qdi")) {
/* Check for a card */
local_irq_save(flags);
res = inb_p(port);
outb_p(r, port);
local_irq_restore(flags);
-
+
/* Fail */
if (res == 0x19)
{
release_region(port, 2);
continue;
}
-
+
/* Passes the presence test */
r = inb_p(port + 1); /* Check port agrees with port set */
if ((r & 2) >> 1 != i) {
continue;
}
- /* Check card type */
+ /* Check card type */
if ((r & 0xF0) == 0xC0) {
/* QD6500: single channel */
if (r & 8) {
int i;
for (i = 0; i < nr_qdi_host; i++) {
- ata_host_remove(qdi_host[i]);
+ ata_host_detach(qdi_host[i]);
/* Free the control resource. The 6580 dual channel has the resources
* claimed as a pair of 2 byte resources so we need no special cases...
*/
release_region(qdi_data[i].timing, 2);
platform_device_unregister(qdi_data[i].platform_dev);
- }
+ }
}
MODULE_AUTHOR("Alan Cox");