]> err.no Git - linux-2.6/commitdiff
pata_pcmcia: Add support for dumb 8bit IDE emulations
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Mon, 15 Oct 2007 19:44:11 +0000 (20:44 +0100)
committerJeff Garzik <jeff@garzik.org>
Wed, 23 Jan 2008 10:24:15 +0000 (05:24 -0500)
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/ata/pata_pcmcia.c

index fd36099428a45cbf85b84a46d457bcef57a56209..bbd4d70b92deedd0ff93a8703b5f86c0fe739c4b 100644 (file)
@@ -86,6 +86,44 @@ static int pcmcia_set_mode(struct ata_link *link, struct ata_device **r_failed_d
        return ata_do_set_mode(link, r_failed_dev);
 }
 
+/**
+ *     pcmcia_set_mode_8bit    -       PCMCIA specific mode setup
+ *     @link: link
+ *     @r_failed_dev: Return pointer for failed device
+ *
+ *     For the simple emulated 8bit stuff the less we do the better.
+ */
+
+static int pcmcia_set_mode_8bit(struct ata_link *link,
+                               struct ata_device **r_failed_dev)
+{
+       return 0;
+}
+
+/**
+ *     ata_data_xfer_8bit       -      Transfer data by 8bit PIO
+ *     @adev: device to target
+ *     @buf: data buffer
+ *     @buflen: buffer length
+ *     @write_data: read/write
+ *
+ *     Transfer data from/to the device data register by 8 bit PIO.
+ *
+ *     LOCKING:
+ *     Inherited from caller.
+ */
+
+static void ata_data_xfer_8bit(struct ata_device *adev, unsigned char *buf,
+                  unsigned int buflen, int write_data)
+{
+       struct ata_port *ap = adev->link->ap;
+       if (write_data)
+               iowrite8_rep(ap->ioaddr.data_addr, buf, buflen);
+       else
+               ioread8_rep(ap->ioaddr.data_addr, buf, buflen);
+}
+
+
 static struct scsi_host_template pcmcia_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
@@ -129,12 +167,38 @@ static struct ata_port_operations pcmcia_port_ops = {
        .port_start     = ata_sff_port_start,
 };
 
+static struct ata_port_operations pcmcia_8bit_port_ops = {
+       .set_mode       = pcmcia_set_mode_8bit,
+       .tf_load        = ata_tf_load,
+       .tf_read        = ata_tf_read,
+       .check_status   = ata_check_status,
+       .exec_command   = ata_exec_command,
+       .dev_select     = ata_std_dev_select,
+
+       .freeze         = ata_bmdma_freeze,
+       .thaw           = ata_bmdma_thaw,
+       .error_handler  = ata_bmdma_error_handler,
+       .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
+
+       .qc_prep        = ata_qc_prep,
+       .qc_issue       = ata_qc_issue_prot,
+
+       .data_xfer      = ata_data_xfer_8bit,
+
+       .irq_clear      = ata_bmdma_irq_clear,
+       .irq_on         = ata_irq_on,
+
+       .port_start     = ata_sff_port_start,
+};
+
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
 /**
  *     pcmcia_init_one         -       attach a PCMCIA interface
  *     @pdev: pcmcia device
+ *     @ops: operations for this device
  *
  *     Register a PCMCIA IDE interface. Such interfaces are PIO 0 and
  *     shared IRQ.
@@ -157,6 +221,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
        unsigned long io_base, ctl_base;
        void __iomem *io_addr, *ctl_addr;
 
+       struct ata_port_operations *ops = &pcmcia_port_ops;
+
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (info == NULL)
                return -ENOMEM;
@@ -284,6 +350,8 @@ next_entry:
        if (pdev->io.NumPorts1 >= 0x20)
                printk(KERN_WARNING DRV_NAME ": second channel not yet supported.\n");
 
+       if (pdev->manf_id == 0x0097 && pdev->card_id == 0x1620)
+               ops = &pcmcia_8bit_port_ops;
        /*
         *      Having done the PCMCIA plumbing the ATA side is relatively
         *      sane.
@@ -294,7 +362,7 @@ next_entry:
                goto failed;
        ap = host->ports[0];
 
-       ap->ops = &pcmcia_port_ops;
+       ap->ops = ops;
        ap->pio_mask = 1;               /* ISA so PIO 0 cycles */
        ap->flags |= ATA_FLAG_SLAVE_POSS;
        ap->ioaddr.cmd_addr = io_addr;
@@ -360,6 +428,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
        PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
        PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),        /* SanDisk CFA */
+       PCMCIA_DEVICE_MANF_CARD(0x0097, 0x1620),        /* TI emulated */
        PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
        PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
        PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */