0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/kernel.h>
0025 #include <linux/module.h>
0026 #include <linux/pci.h>
0027 #include <linux/blkdev.h>
0028 #include <linux/delay.h>
0029 #include <scsi/scsi_host.h>
0030 #include <linux/libata.h>
0031
0032 #define DRV_NAME "pata_triflex"
0033 #define DRV_VERSION "0.2.8"
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 static int triflex_prereset(struct ata_link *link, unsigned long deadline)
0044 {
0045 static const struct pci_bits triflex_enable_bits[] = {
0046 { 0x80, 1, 0x01, 0x01 },
0047 { 0x80, 1, 0x02, 0x02 }
0048 };
0049
0050 struct ata_port *ap = link->ap;
0051 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
0052
0053 if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no]))
0054 return -ENOENT;
0055
0056 return ata_sff_prereset(link, deadline);
0057 }
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 static void triflex_load_timing(struct ata_port *ap, struct ata_device *adev, int speed)
0074 {
0075 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
0076 u32 timing = 0;
0077 u32 triflex_timing, old_triflex_timing;
0078 int channel_offset = ap->port_no ? 0x74: 0x70;
0079 unsigned int is_slave = (adev->devno != 0);
0080
0081
0082 pci_read_config_dword(pdev, channel_offset, &old_triflex_timing);
0083 triflex_timing = old_triflex_timing;
0084
0085 switch(speed)
0086 {
0087 case XFER_MW_DMA_2:
0088 timing = 0x0103;break;
0089 case XFER_MW_DMA_1:
0090 timing = 0x0203;break;
0091 case XFER_MW_DMA_0:
0092 timing = 0x0808;break;
0093 case XFER_SW_DMA_2:
0094 case XFER_SW_DMA_1:
0095 case XFER_SW_DMA_0:
0096 timing = 0x0F0F;break;
0097 case XFER_PIO_4:
0098 timing = 0x0202;break;
0099 case XFER_PIO_3:
0100 timing = 0x0204;break;
0101 case XFER_PIO_2:
0102 timing = 0x0404;break;
0103 case XFER_PIO_1:
0104 timing = 0x0508;break;
0105 case XFER_PIO_0:
0106 timing = 0x0808;break;
0107 default:
0108 BUG();
0109 }
0110 triflex_timing &= ~ (0xFFFF << (16 * is_slave));
0111 triflex_timing |= (timing << (16 * is_slave));
0112
0113 if (triflex_timing != old_triflex_timing)
0114 pci_write_config_dword(pdev, channel_offset, triflex_timing);
0115 }
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 static void triflex_set_piomode(struct ata_port *ap, struct ata_device *adev)
0127 {
0128 triflex_load_timing(ap, adev, adev->pio_mode);
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 static void triflex_bmdma_start(struct ata_queued_cmd *qc)
0143 {
0144 triflex_load_timing(qc->ap, qc->dev, qc->dev->dma_mode);
0145 ata_bmdma_start(qc);
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 static void triflex_bmdma_stop(struct ata_queued_cmd *qc)
0158 {
0159 ata_bmdma_stop(qc);
0160 triflex_load_timing(qc->ap, qc->dev, qc->dev->pio_mode);
0161 }
0162
0163 static struct scsi_host_template triflex_sht = {
0164 ATA_BMDMA_SHT(DRV_NAME),
0165 };
0166
0167 static struct ata_port_operations triflex_port_ops = {
0168 .inherits = &ata_bmdma_port_ops,
0169 .bmdma_start = triflex_bmdma_start,
0170 .bmdma_stop = triflex_bmdma_stop,
0171 .cable_detect = ata_cable_40wire,
0172 .set_piomode = triflex_set_piomode,
0173 .prereset = triflex_prereset,
0174 };
0175
0176 static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
0177 {
0178 static const struct ata_port_info info = {
0179 .flags = ATA_FLAG_SLAVE_POSS,
0180 .pio_mask = ATA_PIO4,
0181 .mwdma_mask = ATA_MWDMA2,
0182 .port_ops = &triflex_port_ops
0183 };
0184 const struct ata_port_info *ppi[] = { &info, NULL };
0185
0186 ata_print_version_once(&dev->dev, DRV_VERSION);
0187
0188 return ata_pci_bmdma_init_one(dev, ppi, &triflex_sht, NULL, 0);
0189 }
0190
0191 static const struct pci_device_id triflex[] = {
0192 { PCI_VDEVICE(COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE), },
0193
0194 { },
0195 };
0196
0197 #ifdef CONFIG_PM_SLEEP
0198 static int triflex_ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
0199 {
0200 struct ata_host *host = pci_get_drvdata(pdev);
0201
0202 ata_host_suspend(host, mesg);
0203
0204
0205
0206
0207
0208 pci_save_state(pdev);
0209
0210 return 0;
0211 }
0212
0213 #endif
0214
0215 static struct pci_driver triflex_pci_driver = {
0216 .name = DRV_NAME,
0217 .id_table = triflex,
0218 .probe = triflex_init_one,
0219 .remove = ata_pci_remove_one,
0220 #ifdef CONFIG_PM_SLEEP
0221 .suspend = triflex_ata_pci_device_suspend,
0222 .resume = ata_pci_device_resume,
0223 #endif
0224 };
0225
0226 module_pci_driver(triflex_pci_driver);
0227
0228 MODULE_AUTHOR("Alan Cox");
0229 MODULE_DESCRIPTION("low-level driver for Compaq Triflex");
0230 MODULE_LICENSE("GPL");
0231 MODULE_DEVICE_TABLE(pci, triflex);
0232 MODULE_VERSION(DRV_VERSION);