Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 
0003 /*
0004  *   pata-isapnp.c - ISA PnP PATA controller driver.
0005  *   Copyright 2005/2006 Red Hat Inc, all rights reserved.
0006  *
0007  *   Based in part on ide-pnp.c by Andrey Panin <pazke@donpac.ru>
0008  */
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/isapnp.h>
0013 #include <linux/init.h>
0014 #include <linux/blkdev.h>
0015 #include <linux/delay.h>
0016 #include <scsi/scsi_host.h>
0017 #include <linux/ata.h>
0018 #include <linux/libata.h>
0019 
0020 #define DRV_NAME "pata_isapnp"
0021 #define DRV_VERSION "0.2.5"
0022 
0023 static struct scsi_host_template isapnp_sht = {
0024     ATA_PIO_SHT(DRV_NAME),
0025 };
0026 
0027 static struct ata_port_operations isapnp_port_ops = {
0028     .inherits   = &ata_sff_port_ops,
0029     .cable_detect   = ata_cable_40wire,
0030 };
0031 
0032 static struct ata_port_operations isapnp_noalt_port_ops = {
0033     .inherits   = &ata_sff_port_ops,
0034     .cable_detect   = ata_cable_40wire,
0035     /* No altstatus so we don't want to use the lost interrupt poll */
0036     .lost_interrupt = ATA_OP_NULL,
0037 };
0038 
0039 /**
0040  *  isapnp_init_one     -   attach an isapnp interface
0041  *  @idev: PnP device
0042  *  @dev_id: matching detect line
0043  *
0044  *  Register an ISA bus IDE interface. Such interfaces are PIO 0 and
0045  *  non shared IRQ.
0046  */
0047 
0048 static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id)
0049 {
0050     struct ata_host *host;
0051     struct ata_port *ap;
0052     void __iomem *cmd_addr, *ctl_addr;
0053     int irq = 0;
0054     irq_handler_t handler = NULL;
0055 
0056     if (pnp_port_valid(idev, 0) == 0)
0057         return -ENODEV;
0058 
0059     if (pnp_irq_valid(idev, 0)) {
0060         irq = pnp_irq(idev, 0);
0061         handler = ata_sff_interrupt;
0062     }
0063 
0064     /* allocate host */
0065     host = ata_host_alloc(&idev->dev, 1);
0066     if (!host)
0067         return -ENOMEM;
0068 
0069     /* acquire resources and fill host */
0070     cmd_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 0), 8);
0071     if (!cmd_addr)
0072         return -ENOMEM;
0073 
0074     ap = host->ports[0];
0075 
0076     ap->ops = &isapnp_noalt_port_ops;
0077     ap->pio_mask = ATA_PIO0;
0078     ap->flags |= ATA_FLAG_SLAVE_POSS;
0079 
0080     ap->ioaddr.cmd_addr = cmd_addr;
0081 
0082     if (pnp_port_valid(idev, 1)) {
0083         ctl_addr = devm_ioport_map(&idev->dev,
0084                        pnp_port_start(idev, 1), 1);
0085         ap->ioaddr.altstatus_addr = ctl_addr;
0086         ap->ioaddr.ctl_addr = ctl_addr;
0087         ap->ops = &isapnp_port_ops;
0088     }
0089 
0090     ata_sff_std_ports(&ap->ioaddr);
0091 
0092     ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
0093               (unsigned long long)pnp_port_start(idev, 0),
0094               (unsigned long long)pnp_port_start(idev, 1));
0095 
0096     /* activate */
0097     return ata_host_activate(host, irq, handler, 0,
0098                  &isapnp_sht);
0099 }
0100 
0101 /**
0102  *  isapnp_remove_one   -   unplug an isapnp interface
0103  *  @idev: PnP device
0104  *
0105  *  Remove a previously configured PnP ATA port. Called only on module
0106  *  unload events as the core does not currently deal with ISAPnP docking.
0107  */
0108 
0109 static void isapnp_remove_one(struct pnp_dev *idev)
0110 {
0111     struct device *dev = &idev->dev;
0112     struct ata_host *host = dev_get_drvdata(dev);
0113 
0114     ata_host_detach(host);
0115 }
0116 
0117 static struct pnp_device_id isapnp_devices[] = {
0118     /* Generic ESDI/IDE/ATA compatible hard disk controller */
0119     {.id = "PNP0600", .driver_data = 0},
0120     {.id = ""}
0121 };
0122 
0123 MODULE_DEVICE_TABLE(pnp, isapnp_devices);
0124 
0125 static struct pnp_driver isapnp_driver = {
0126     .name       = DRV_NAME,
0127     .id_table   = isapnp_devices,
0128     .probe      = isapnp_init_one,
0129     .remove     = isapnp_remove_one,
0130 };
0131 
0132 module_pnp_driver(isapnp_driver);
0133 MODULE_AUTHOR("Alan Cox");
0134 MODULE_DESCRIPTION("low-level driver for ISA PnP ATA");
0135 MODULE_LICENSE("GPL");
0136 MODULE_VERSION(DRV_VERSION);