diff options
-rw-r--r-- | drivers/ata/pata_pcmcia.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index fd36099428a..bbd4d70b92d 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -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 */ |