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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [drivers/] [ata/] [pata_acpi.c] - Blame information for rev 17

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

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *      ACPI PATA driver
3
 *
4
 *      (c) 2007 Red Hat  <alan@redhat.com>
5
 */
6
 
7
#include <linux/kernel.h>
8
#include <linux/module.h>
9
#include <linux/pci.h>
10
#include <linux/init.h>
11
#include <linux/blkdev.h>
12
#include <linux/delay.h>
13
#include <linux/device.h>
14
#include <scsi/scsi_host.h>
15
#include <acpi/acpi_bus.h>
16
#include <acpi/acnames.h>
17
#include <acpi/acnamesp.h>
18
#include <acpi/acparser.h>
19
#include <acpi/acexcep.h>
20
#include <acpi/acmacros.h>
21
#include <acpi/actypes.h>
22
 
23
#include <linux/libata.h>
24
#include <linux/ata.h>
25
 
26
#define DRV_NAME        "pata_acpi"
27
#define DRV_VERSION     "0.2.3"
28
 
29
struct pata_acpi {
30
        struct ata_acpi_gtm gtm;
31
        void *last;
32
        unsigned long mask[2];
33
};
34
 
35
/**
36
 *      pacpi_pre_reset -       check for 40/80 pin
37
 *      @ap: Port
38
 *      @deadline: deadline jiffies for the operation
39
 *
40
 *      Perform the PATA port setup we need.
41
 */
42
 
43
static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline)
44
{
45
        struct ata_port *ap = link->ap;
46
        struct pata_acpi *acpi = ap->private_data;
47
        if (ap->acpi_handle == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
48
                return -ENODEV;
49
 
50
        return ata_std_prereset(link, deadline);
51
}
52
 
53
/**
54
 *      pacpi_cable_detect      -       cable type detection
55
 *      @ap: port to detect
56
 *
57
 *      Perform device specific cable detection
58
 */
59
 
60
static int pacpi_cable_detect(struct ata_port *ap)
61
{
62
        struct pata_acpi *acpi = ap->private_data;
63
 
64
        if ((acpi->mask[0] | acpi->mask[1]) & (0xF8 << ATA_SHIFT_UDMA))
65
                return ATA_CBL_PATA80;
66
        else
67
                return ATA_CBL_PATA40;
68
}
69
 
70
/**
71
 *      pacpi_error_handler - Setup and error handler
72
 *      @ap: Port to handle
73
 *
74
 *      LOCKING:
75
 *      None (inherited from caller).
76
 */
77
 
78
static void pacpi_error_handler(struct ata_port *ap)
79
{
80
        return ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset,
81
                                  NULL, ata_std_postreset);
82
}
83
 
84
/* Welcome to ACPI, bring a bucket */
85
static const unsigned int pio_cycle[7] = {
86
        600, 383, 240, 180, 120, 100, 80
87
};
88
static const unsigned int mwdma_cycle[5] = {
89
        480, 150, 120, 100, 80
90
};
91
static const unsigned int udma_cycle[7] = {
92
        120, 80, 60, 45, 30, 20, 15
93
};
94
 
95
/**
96
 *      pacpi_discover_modes    -       filter non ACPI modes
97
 *      @adev: ATA device
98
 *      @mask: proposed modes
99
 *
100
 *      Try the modes available and see which ones the ACPI method will
101
 *      set up sensibly. From this we get a mask of ACPI modes we can use
102
 */
103
 
104
static unsigned long pacpi_discover_modes(struct ata_port *ap, struct ata_device *adev)
105
{
106
        int unit = adev->devno;
107
        struct pata_acpi *acpi = ap->private_data;
108
        int i;
109
        u32 t;
110
        unsigned long mask = (0x7f << ATA_SHIFT_UDMA) | (0x7 << ATA_SHIFT_MWDMA) | (0x1F << ATA_SHIFT_PIO);
111
 
112
        struct ata_acpi_gtm probe;
113
 
114
        probe = acpi->gtm;
115
 
116
        /* We always use the 0 slot for crap hardware */
117
        if (!(probe.flags & 0x10))
118
                unit = 0;
119
 
120
        ata_acpi_gtm(ap, &probe);
121
 
122
        /* Start by scanning for PIO modes */
123
        for (i = 0; i < 7; i++) {
124
                t = probe.drive[unit].pio;
125
                if (t <= pio_cycle[i]) {
126
                        mask |= (2 << (ATA_SHIFT_PIO + i)) - 1;
127
                        break;
128
                }
129
        }
130
 
131
        /* See if we have MWDMA or UDMA data. We don't bother with MWDMA
132
           if UDMA is availabe as this means the BIOS set UDMA and our
133
           error changedown if it works is UDMA to PIO anyway */
134
        if (probe.flags & (1 << (2 * unit))) {
135
                /* MWDMA */
136
                for (i = 0; i < 5; i++) {
137
                        t = probe.drive[unit].dma;
138
                        if (t <= mwdma_cycle[i]) {
139
                                mask |= (2 << (ATA_SHIFT_MWDMA + i)) - 1;
140
                                break;
141
                        }
142
                }
143
        } else {
144
                /* UDMA */
145
                for (i = 0; i < 7; i++) {
146
                        t = probe.drive[unit].dma;
147
                        if (t <= udma_cycle[i]) {
148
                                mask |= (2 << (ATA_SHIFT_UDMA + i)) - 1;
149
                                break;
150
                        }
151
                }
152
        }
153
        if (mask & (0xF8 << ATA_SHIFT_UDMA))
154
                ap->cbl = ATA_CBL_PATA80;
155
        return mask;
156
}
157
 
158
/**
159
 *      pacpi_mode_filter       -       mode filter for ACPI
160
 *      @adev: device
161
 *      @mask: mask of valid modes
162
 *
163
 *      Filter the valid mode list according to our own specific rules, in
164
 *      this case the list of discovered valid modes obtained by ACPI probing
165
 */
166
 
167
static unsigned long pacpi_mode_filter(struct ata_device *adev, unsigned long mask)
168
{
169
        struct pata_acpi *acpi = adev->link->ap->private_data;
170
        return ata_pci_default_filter(adev, mask & acpi->mask[adev->devno]);
171
}
172
 
173
/**
174
 *      pacpi_set_piomode       -       set initial PIO mode data
175
 *      @ap: ATA interface
176
 *      @adev: ATA device
177
 */
178
 
179
static void pacpi_set_piomode(struct ata_port *ap, struct ata_device *adev)
180
{
181
        int unit = adev->devno;
182
        struct pata_acpi *acpi = ap->private_data;
183
 
184
        if (!(acpi->gtm.flags & 0x10))
185
                unit = 0;
186
 
187
        /* Now stuff the nS values into the structure */
188
        acpi->gtm.drive[unit].pio = pio_cycle[adev->pio_mode - XFER_PIO_0];
189
        ata_acpi_stm(ap, &acpi->gtm);
190
        /* See what mode we actually got */
191
        ata_acpi_gtm(ap, &acpi->gtm);
192
}
193
 
194
/**
195
 *      pacpi_set_dmamode       -       set initial DMA mode data
196
 *      @ap: ATA interface
197
 *      @adev: ATA device
198
 */
199
 
200
static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev)
201
{
202
        int unit = adev->devno;
203
        struct pata_acpi *acpi = ap->private_data;
204
 
205
        if (!(acpi->gtm.flags & 0x10))
206
                unit = 0;
207
 
208
        /* Now stuff the nS values into the structure */
209
        if (adev->dma_mode >= XFER_UDMA_0) {
210
                acpi->gtm.drive[unit].dma = udma_cycle[adev->dma_mode - XFER_UDMA_0];
211
                acpi->gtm.flags |= (1 << (2 * unit));
212
        } else {
213
                acpi->gtm.drive[unit].dma = mwdma_cycle[adev->dma_mode - XFER_MW_DMA_0];
214
                acpi->gtm.flags &= ~(1 << (2 * unit));
215
        }
216
        ata_acpi_stm(ap, &acpi->gtm);
217
        /* See what mode we actually got */
218
        ata_acpi_gtm(ap, &acpi->gtm);
219
}
220
 
221
/**
222
 *      pacpi_qc_issue_prot     -       command issue
223
 *      @qc: command pending
224
 *
225
 *      Called when the libata layer is about to issue a command. We wrap
226
 *      this interface so that we can load the correct ATA timings if
227
 *      neccessary.
228
 */
229
 
230
static unsigned int pacpi_qc_issue_prot(struct ata_queued_cmd *qc)
231
{
232
        struct ata_port *ap = qc->ap;
233
        struct ata_device *adev = qc->dev;
234
        struct pata_acpi *acpi = ap->private_data;
235
 
236
        if (acpi->gtm.flags & 0x10)
237
                return ata_qc_issue_prot(qc);
238
 
239
        if (adev != acpi->last) {
240
                pacpi_set_piomode(ap, adev);
241
                if (adev->dma_mode)
242
                        pacpi_set_dmamode(ap, adev);
243
                acpi->last = adev;
244
        }
245
        return ata_qc_issue_prot(qc);
246
}
247
 
248
/**
249
 *      pacpi_port_start        -       port setup
250
 *      @ap: ATA port being set up
251
 *
252
 *      Use the port_start hook to maintain private control structures
253
 */
254
 
255
static int pacpi_port_start(struct ata_port *ap)
256
{
257
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
258
        struct pata_acpi *acpi;
259
 
260
        int ret;
261
 
262
        if (ap->acpi_handle == NULL)
263
                return -ENODEV;
264
 
265
        acpi = ap->private_data = devm_kzalloc(&pdev->dev, sizeof(struct pata_acpi), GFP_KERNEL);
266
        if (ap->private_data == NULL)
267
                return -ENOMEM;
268
        acpi->mask[0] = pacpi_discover_modes(ap, &ap->link.device[0]);
269
        acpi->mask[1] = pacpi_discover_modes(ap, &ap->link.device[1]);
270
        ret = ata_sff_port_start(ap);
271
        if (ret < 0)
272
                return ret;
273
 
274
        return ret;
275
}
276
 
277
static struct scsi_host_template pacpi_sht = {
278
        .module                 = THIS_MODULE,
279
        .name                   = DRV_NAME,
280
        .ioctl                  = ata_scsi_ioctl,
281
        .queuecommand           = ata_scsi_queuecmd,
282
        .can_queue              = ATA_DEF_QUEUE,
283
        .this_id                = ATA_SHT_THIS_ID,
284
        .sg_tablesize           = LIBATA_MAX_PRD,
285
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
286
        .emulated               = ATA_SHT_EMULATED,
287
        .use_clustering         = ATA_SHT_USE_CLUSTERING,
288
        .proc_name              = DRV_NAME,
289
        .dma_boundary           = ATA_DMA_BOUNDARY,
290
        .slave_configure        = ata_scsi_slave_config,
291
        .slave_destroy          = ata_scsi_slave_destroy,
292
        /* Use standard CHS mapping rules */
293
        .bios_param             = ata_std_bios_param,
294
};
295
 
296
static const struct ata_port_operations pacpi_ops = {
297
        .set_piomode            = pacpi_set_piomode,
298
        .set_dmamode            = pacpi_set_dmamode,
299
        .mode_filter            = pacpi_mode_filter,
300
 
301
        /* Task file is PCI ATA format, use helpers */
302
        .tf_load                = ata_tf_load,
303
        .tf_read                = ata_tf_read,
304
        .check_status           = ata_check_status,
305
        .exec_command           = ata_exec_command,
306
        .dev_select             = ata_std_dev_select,
307
 
308
        .freeze                 = ata_bmdma_freeze,
309
        .thaw                   = ata_bmdma_thaw,
310
        .error_handler          = pacpi_error_handler,
311
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
312
        .cable_detect           = pacpi_cable_detect,
313
 
314
        /* BMDMA handling is PCI ATA format, use helpers */
315
        .bmdma_setup            = ata_bmdma_setup,
316
        .bmdma_start            = ata_bmdma_start,
317
        .bmdma_stop             = ata_bmdma_stop,
318
        .bmdma_status           = ata_bmdma_status,
319
        .qc_prep                = ata_qc_prep,
320
        .qc_issue               = pacpi_qc_issue_prot,
321
        .data_xfer              = ata_data_xfer,
322
 
323
        /* Timeout handling */
324
        .irq_handler            = ata_interrupt,
325
        .irq_clear              = ata_bmdma_irq_clear,
326
        .irq_on                 = ata_irq_on,
327
 
328
        /* Generic PATA PCI ATA helpers */
329
        .port_start             = pacpi_port_start,
330
};
331
 
332
 
333
/**
334
 *      pacpi_init_one - Register ACPI ATA PCI device with kernel services
335
 *      @pdev: PCI device to register
336
 *      @ent: Entry in pacpi_pci_tbl matching with @pdev
337
 *
338
 *      Called from kernel PCI layer.
339
 *
340
 *      LOCKING:
341
 *      Inherited from PCI layer (may sleep).
342
 *
343
 *      RETURNS:
344
 *      Zero on success, or -ERRNO value.
345
 */
346
 
347
static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
348
{
349
        static const struct ata_port_info info = {
350
                .sht            = &pacpi_sht,
351
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
352
 
353
                .pio_mask       = 0x1f,
354
                .mwdma_mask     = 0x07,
355
                .udma_mask      = 0x7f,
356
 
357
                .port_ops       = &pacpi_ops,
358
        };
359
        const struct ata_port_info *ppi[] = { &info, NULL };
360
        return ata_pci_init_one(pdev, ppi);
361
}
362
 
363
static const struct pci_device_id pacpi_pci_tbl[] = {
364
        { PCI_ANY_ID,           PCI_ANY_ID,                        PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 1},
365
        { }     /* terminate list */
366
};
367
 
368
static struct pci_driver pacpi_pci_driver = {
369
        .name                   = DRV_NAME,
370
        .id_table               = pacpi_pci_tbl,
371
        .probe                  = pacpi_init_one,
372
        .remove                 = ata_pci_remove_one,
373
#ifdef CONFIG_PM
374
        .suspend                = ata_pci_device_suspend,
375
        .resume                 = ata_pci_device_resume,
376
#endif
377
};
378
 
379
static int __init pacpi_init(void)
380
{
381
        return pci_register_driver(&pacpi_pci_driver);
382
}
383
 
384
static void __exit pacpi_exit(void)
385
{
386
        pci_unregister_driver(&pacpi_pci_driver);
387
}
388
 
389
module_init(pacpi_init);
390
module_exit(pacpi_exit);
391
 
392
MODULE_AUTHOR("Alan Cox");
393
MODULE_DESCRIPTION("SCSI low-level driver for ATA in ACPI mode");
394
MODULE_LICENSE("GPL");
395
MODULE_DEVICE_TABLE(pci, pacpi_pci_tbl);
396
MODULE_VERSION(DRV_VERSION);
397
 

powered by: WebSVN 2.1.0

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