OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [ata/] [pata_radisys.c] - Blame information for rev 65

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *    pata_radisys.c - Intel PATA/SATA controllers
3
 *
4
 *      (C) 2006 Red Hat <alan@redhat.com>
5
 *
6
 *    Some parts based on ata_piix.c by Jeff Garzik and others.
7
 *
8
 *    A PIIX relative, this device has a single ATA channel and no
9
 *    slave timings, SITRE or PPE. In that sense it is a close relative
10
 *    of the original PIIX. It does however support UDMA 33/66 per channel
11
 *    although no other modes/timings. Also lacking is 32bit I/O on the ATA
12
 *    port.
13
 */
14
 
15
#include <linux/kernel.h>
16
#include <linux/module.h>
17
#include <linux/pci.h>
18
#include <linux/init.h>
19
#include <linux/blkdev.h>
20
#include <linux/delay.h>
21
#include <linux/device.h>
22
#include <scsi/scsi_host.h>
23
#include <linux/libata.h>
24
#include <linux/ata.h>
25
 
26
#define DRV_NAME        "pata_radisys"
27
#define DRV_VERSION     "0.4.4"
28
 
29
/**
30
 *      radisys_set_piomode - Initialize host controller PATA PIO timings
31
 *      @ap: ATA port
32
 *      @adev: Device whose timings we are configuring
33
 *
34
 *      Set PIO mode for device, in host controller PCI config space.
35
 *
36
 *      LOCKING:
37
 *      None (inherited from caller).
38
 */
39
 
40
static void radisys_set_piomode (struct ata_port *ap, struct ata_device *adev)
41
{
42
        unsigned int pio        = adev->pio_mode - XFER_PIO_0;
43
        struct pci_dev *dev     = to_pci_dev(ap->host->dev);
44
        u16 idetm_data;
45
        int control = 0;
46
 
47
        /*
48
         *      See Intel Document 298600-004 for the timing programing rules
49
         *      for PIIX/ICH. Note that the early PIIX does not have the slave
50
         *      timing port at 0x44. The Radisys is a relative of the PIIX
51
         *      but not the same so be careful.
52
         */
53
 
54
        static const     /* ISP  RTC */
55
        u8 timings[][2] = { { 0, 0 },     /* Check me */
56
                            { 0, 0 },
57
                            { 1, 1 },
58
                            { 2, 2 },
59
                            { 3, 3 }, };
60
 
61
        if (pio > 0)
62
                control |= 1;   /* TIME1 enable */
63
        if (ata_pio_need_iordy(adev))
64
                control |= 2;   /* IE IORDY */
65
 
66
        pci_read_config_word(dev, 0x40, &idetm_data);
67
 
68
        /* Enable IE and TIME as appropriate. Clear the other
69
           drive timing bits */
70
        idetm_data &= 0xCCCC;
71
        idetm_data |= (control << (4 * adev->devno));
72
        idetm_data |= (timings[pio][0] << 12) |
73
                        (timings[pio][1] << 8);
74
        pci_write_config_word(dev, 0x40, idetm_data);
75
 
76
        /* Track which port is configured */
77
        ap->private_data = adev;
78
}
79
 
80
/**
81
 *      radisys_set_dmamode - Initialize host controller PATA DMA timings
82
 *      @ap: Port whose timings we are configuring
83
 *      @adev: Device to program
84
 *      @isich: True if the device is an ICH and has IOCFG registers
85
 *
86
 *      Set MWDMA mode for device, in host controller PCI config space.
87
 *
88
 *      LOCKING:
89
 *      None (inherited from caller).
90
 */
91
 
92
static void radisys_set_dmamode (struct ata_port *ap, struct ata_device *adev)
93
{
94
        struct pci_dev *dev     = to_pci_dev(ap->host->dev);
95
        u16 idetm_data;
96
        u8 udma_enable;
97
 
98
        static const     /* ISP  RTC */
99
        u8 timings[][2] = { { 0, 0 },
100
                            { 0, 0 },
101
                            { 1, 1 },
102
                            { 2, 2 },
103
                            { 3, 3 }, };
104
 
105
        /*
106
         * MWDMA is driven by the PIO timings. We must also enable
107
         * IORDY unconditionally.
108
         */
109
 
110
        pci_read_config_word(dev, 0x40, &idetm_data);
111
        pci_read_config_byte(dev, 0x48, &udma_enable);
112
 
113
        if (adev->dma_mode < XFER_UDMA_0) {
114
                unsigned int mwdma      = adev->dma_mode - XFER_MW_DMA_0;
115
                const unsigned int needed_pio[3] = {
116
                        XFER_PIO_0, XFER_PIO_3, XFER_PIO_4
117
                };
118
                int pio = needed_pio[mwdma] - XFER_PIO_0;
119
                int control = 3;        /* IORDY|TIME0 */
120
 
121
                /* If the drive MWDMA is faster than it can do PIO then
122
                   we must force PIO0 for PIO cycles. */
123
 
124
                if (adev->pio_mode < needed_pio[mwdma])
125
                        control = 1;
126
 
127
                /* Mask out the relevant control and timing bits we will load. Also
128
                   clear the other drive TIME register as a precaution */
129
 
130
                idetm_data &= 0xCCCC;
131
                idetm_data |= control << (4 * adev->devno);
132
                idetm_data |= (timings[pio][0] << 12) | (timings[pio][1] << 8);
133
 
134
                udma_enable &= ~(1 << adev->devno);
135
        } else {
136
                u8 udma_mode;
137
 
138
                /* UDMA66 on: UDMA 33 and 66 are switchable via register 0x4A */
139
 
140
                pci_read_config_byte(dev, 0x4A, &udma_mode);
141
 
142
                if (adev->xfer_mode == XFER_UDMA_2)
143
                        udma_mode &= ~ (1 << adev->devno);
144
                else /* UDMA 4 */
145
                        udma_mode |= (1 << adev->devno);
146
 
147
                pci_write_config_byte(dev, 0x4A, udma_mode);
148
 
149
                udma_enable |= (1 << adev->devno);
150
        }
151
        pci_write_config_word(dev, 0x40, idetm_data);
152
        pci_write_config_byte(dev, 0x48, udma_enable);
153
 
154
        /* Track which port is configured */
155
        ap->private_data = adev;
156
}
157
 
158
/**
159
 *      radisys_qc_issue_prot   -       command issue
160
 *      @qc: command pending
161
 *
162
 *      Called when the libata layer is about to issue a command. We wrap
163
 *      this interface so that we can load the correct ATA timings if
164
 *      necessary. Our logic also clears TIME0/TIME1 for the other device so
165
 *      that, even if we get this wrong, cycles to the other device will
166
 *      be made PIO0.
167
 */
168
 
169
static unsigned int radisys_qc_issue_prot(struct ata_queued_cmd *qc)
170
{
171
        struct ata_port *ap = qc->ap;
172
        struct ata_device *adev = qc->dev;
173
 
174
        if (adev != ap->private_data) {
175
                /* UDMA timing is not shared */
176
                if (adev->dma_mode < XFER_UDMA_0) {
177
                        if (adev->dma_mode)
178
                                radisys_set_dmamode(ap, adev);
179
                        else if (adev->pio_mode)
180
                                radisys_set_piomode(ap, adev);
181
                }
182
        }
183
        return ata_qc_issue_prot(qc);
184
}
185
 
186
 
187
static struct scsi_host_template radisys_sht = {
188
        .module                 = THIS_MODULE,
189
        .name                   = DRV_NAME,
190
        .ioctl                  = ata_scsi_ioctl,
191
        .queuecommand           = ata_scsi_queuecmd,
192
        .can_queue              = ATA_DEF_QUEUE,
193
        .this_id                = ATA_SHT_THIS_ID,
194
        .sg_tablesize           = LIBATA_MAX_PRD,
195
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
196
        .emulated               = ATA_SHT_EMULATED,
197
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
198
        .proc_name              = DRV_NAME,
199
        .dma_boundary           = ATA_DMA_BOUNDARY,
200
        .slave_configure        = ata_scsi_slave_config,
201
        .slave_destroy          = ata_scsi_slave_destroy,
202
        .bios_param             = ata_std_bios_param,
203
};
204
 
205
static const struct ata_port_operations radisys_pata_ops = {
206
        .set_piomode            = radisys_set_piomode,
207
        .set_dmamode            = radisys_set_dmamode,
208
        .mode_filter            = ata_pci_default_filter,
209
 
210
        .tf_load                = ata_tf_load,
211
        .tf_read                = ata_tf_read,
212
        .check_status           = ata_check_status,
213
        .exec_command           = ata_exec_command,
214
        .dev_select             = ata_std_dev_select,
215
 
216
        .freeze                 = ata_bmdma_freeze,
217
        .thaw                   = ata_bmdma_thaw,
218
        .error_handler          = ata_bmdma_error_handler,
219
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
220
        .cable_detect           = ata_cable_unknown,
221
 
222
        .bmdma_setup            = ata_bmdma_setup,
223
        .bmdma_start            = ata_bmdma_start,
224
        .bmdma_stop             = ata_bmdma_stop,
225
        .bmdma_status           = ata_bmdma_status,
226
        .qc_prep                = ata_qc_prep,
227
        .qc_issue               = radisys_qc_issue_prot,
228
        .data_xfer              = ata_data_xfer,
229
 
230
        .irq_handler            = ata_interrupt,
231
        .irq_clear              = ata_bmdma_irq_clear,
232
        .irq_on                 = ata_irq_on,
233
 
234
        .port_start             = ata_sff_port_start,
235
};
236
 
237
 
238
/**
239
 *      radisys_init_one - Register PIIX ATA PCI device with kernel services
240
 *      @pdev: PCI device to register
241
 *      @ent: Entry in radisys_pci_tbl matching with @pdev
242
 *
243
 *      Called from kernel PCI layer.  We probe for combined mode (sigh),
244
 *      and then hand over control to libata, for it to do the rest.
245
 *
246
 *      LOCKING:
247
 *      Inherited from PCI layer (may sleep).
248
 *
249
 *      RETURNS:
250
 *      Zero on success, or -ERRNO value.
251
 */
252
 
253
static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
254
{
255
        static int printed_version;
256
        static const struct ata_port_info info = {
257
                .sht            = &radisys_sht,
258
                .flags          = ATA_FLAG_SLAVE_POSS,
259
                .pio_mask       = 0x1f, /* pio0-4 */
260
                .mwdma_mask     = 0x07, /* mwdma1-2 */
261
                .udma_mask      = 0x14, /* UDMA33/66 only */
262
                .port_ops       = &radisys_pata_ops,
263
        };
264
        const struct ata_port_info *ppi[] = { &info, NULL };
265
 
266
        if (!printed_version++)
267
                dev_printk(KERN_DEBUG, &pdev->dev,
268
                           "version " DRV_VERSION "\n");
269
 
270
        return ata_pci_init_one(pdev, ppi);
271
}
272
 
273
static const struct pci_device_id radisys_pci_tbl[] = {
274
        { PCI_VDEVICE(RADISYS, 0x8201), },
275
 
276
        { }     /* terminate list */
277
};
278
 
279
static struct pci_driver radisys_pci_driver = {
280
        .name                   = DRV_NAME,
281
        .id_table               = radisys_pci_tbl,
282
        .probe                  = radisys_init_one,
283
        .remove                 = ata_pci_remove_one,
284
#ifdef CONFIG_PM
285
        .suspend                = ata_pci_device_suspend,
286
        .resume                 = ata_pci_device_resume,
287
#endif
288
};
289
 
290
static int __init radisys_init(void)
291
{
292
        return pci_register_driver(&radisys_pci_driver);
293
}
294
 
295
static void __exit radisys_exit(void)
296
{
297
        pci_unregister_driver(&radisys_pci_driver);
298
}
299
 
300
module_init(radisys_init);
301
module_exit(radisys_exit);
302
 
303
MODULE_AUTHOR("Alan Cox");
304
MODULE_DESCRIPTION("SCSI low-level driver for Radisys R82600 controllers");
305
MODULE_LICENSE("GPL");
306
MODULE_DEVICE_TABLE(pci, radisys_pci_tbl);
307
MODULE_VERSION(DRV_VERSION);
308
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.