#include <scsi/scsi_host.h>
#define DRV_NAME "pata_ixp4xx_cf"
-#define DRV_VERSION "0.1.1ac1"
+#define DRV_VERSION "0.1.2"
-static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device *adev)
+static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)
{
int i;
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
- if (ata_dev_enabled(dev)) {
+ if (ata_dev_ready(dev)) {
+ ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
dev->pio_mode = XFER_PIO_0;
dev->xfer_mode = XFER_PIO_0;
dev->xfer_shift = ATA_SHIFT_PIO;
{
}
-static void ixp4xx_host_stop (struct ata_host *host)
-{
- struct ixp4xx_pata_data *data = host->dev->platform_data;
-
- iounmap(data->cs0);
- iounmap(data->cs1);
-}
-
static struct scsi_host_template ixp4xx_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
.data_xfer = ixp4xx_mmio_data_xfer,
+ .cable_detect = ata_cable_40wire,
- .irq_handler = ata_interrupt,
.irq_clear = ixp4xx_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ixp4xx_host_stop,
.phy_reset = ixp4xx_phy_reset,
};
static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
struct ixp4xx_pata_data *data)
{
- ioaddr->cmd_addr = (unsigned long) data->cs0;
- ioaddr->altstatus_addr = (unsigned long) data->cs1 + 0x06;
- ioaddr->ctl_addr = (unsigned long) data->cs1 + 0x06;
+ ioaddr->cmd_addr = data->cs0;
+ ioaddr->altstatus_addr = data->cs1 + 0x06;
+ ioaddr->ctl_addr = data->cs1 + 0x06;
ata_std_ports(ioaddr);
* ixp4xx in little endian mode.
*/
- ioaddr->data_addr ^= 0x02;
- ioaddr->cmd_addr ^= 0x03;
- ioaddr->altstatus_addr ^= 0x03;
- ioaddr->ctl_addr ^= 0x03;
- ioaddr->error_addr ^= 0x03;
- ioaddr->feature_addr ^= 0x03;
- ioaddr->nsect_addr ^= 0x03;
- ioaddr->lbal_addr ^= 0x03;
- ioaddr->lbam_addr ^= 0x03;
- ioaddr->lbah_addr ^= 0x03;
- ioaddr->device_addr ^= 0x03;
- ioaddr->status_addr ^= 0x03;
- ioaddr->command_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->data_addr ^= 0x02;
+ *(unsigned long *)&ioaddr->cmd_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->altstatus_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->ctl_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->error_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->feature_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->nsect_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->lbal_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->lbam_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->lbah_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->device_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->status_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->command_addr ^= 0x03;
#endif
}
static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
{
- int ret;
unsigned int irq;
struct resource *cs0, *cs1;
- struct ata_probe_ent ae;
-
+ struct ata_host *host;
+ struct ata_port *ap;
struct ixp4xx_pata_data *data = pdev->dev.platform_data;
+ int rc;
cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!cs0 || !cs1)
return -EINVAL;
+ /* allocate host */
+ host = ata_host_alloc(&pdev->dev, 1);
+ if (!host)
+ return -ENOMEM;
+
+ /* acquire resources and fill host */
pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
- data->cs0 = ioremap(cs0->start, 0x1000);
- data->cs1 = ioremap(cs1->start, 0x1000);
+ data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
+ data->cs1 = devm_ioremap(&pdev->dev, cs1->start, 0x1000);
irq = platform_get_irq(pdev, 0);
if (irq)
- set_irq_type(irq, IRQT_HIGH);
+ set_irq_type(irq, IRQT_RISING);
/* Setup expansion bus chip selects */
*data->cs0_cfg = data->cs0_bits;
*data->cs1_cfg = data->cs1_bits;
- memset(&ae, 0, sizeof(struct ata_probe_ent));
- INIT_LIST_HEAD(&ae.node);
+ ap = host->ports[0];
- ae.dev = &pdev->dev;
- ae.port_ops = &ixp4xx_port_ops;
- ae.sht = &ixp4xx_sht;
- ae.n_ports = 1;
- ae.pio_mask = 0x1f; /* PIO4 */
- ae.irq = irq;
- ae.irq_flags = 0;
- ae.port_flags = ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
- | ATA_FLAG_NO_ATAPI | ATA_FLAG_SRST;
+ ap->ops = &ixp4xx_port_ops;
+ ap->pio_mask = 0x1f; /* PIO4 */
+ ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
/* run in polling mode if no irq has been assigned */
if (!irq)
- ae.port_flags |= ATA_FLAG_PIO_POLLING;
+ ap->flags |= ATA_FLAG_PIO_POLLING;
- ixp4xx_setup_port(&ae.port[0], data);
+ ixp4xx_setup_port(&ap->ioaddr, data);
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
- ret = ata_device_add(&ae);
- if (ret == 0)
- return -ENODEV;
-
- return 0;
+ /* activate host */
+ return ata_host_activate(host, irq, ata_interrupt, 0, &ixp4xx_sht);
}
static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
{
struct ata_host *host = platform_get_drvdata(dev);
- ata_host_remove(host);
- platform_set_drvdata(dev, NULL);
+ ata_host_detach(host);
return 0;
}