~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/scsi/mvme16x_scsi.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Detection routine for the NCR53c710 based MVME16x SCSI Controllers for Linux.
 
3
 *
 
4
 * Based on work by Alan Hourihane
 
5
 *
 
6
 * Rewritten to use 53c700.c by Kars de Jong <jongk@linux-m68k.org>
 
7
 */
 
8
 
 
9
#include <linux/module.h>
 
10
#include <linux/blkdev.h>
 
11
#include <linux/device.h>
 
12
#include <linux/platform_device.h>
 
13
#include <linux/init.h>
 
14
#include <linux/interrupt.h>
 
15
#include <linux/slab.h>
 
16
#include <asm/mvme16xhw.h>
 
17
#include <scsi/scsi_host.h>
 
18
#include <scsi/scsi_device.h>
 
19
#include <scsi/scsi_transport.h>
 
20
#include <scsi/scsi_transport_spi.h>
 
21
 
 
22
#include "53c700.h"
 
23
 
 
24
MODULE_AUTHOR("Kars de Jong <jongk@linux-m68k.org>");
 
25
MODULE_DESCRIPTION("MVME16x NCR53C710 driver");
 
26
MODULE_LICENSE("GPL");
 
27
 
 
28
static struct scsi_host_template mvme16x_scsi_driver_template = {
 
29
        .name                   = "MVME16x NCR53c710 SCSI",
 
30
        .proc_name              = "MVME16x",
 
31
        .this_id                = 7,
 
32
        .module                 = THIS_MODULE,
 
33
};
 
34
 
 
35
static struct platform_device *mvme16x_scsi_device;
 
36
 
 
37
static __devinit int
 
38
mvme16x_probe(struct platform_device *dev)
 
39
{
 
40
        struct Scsi_Host * host = NULL;
 
41
        struct NCR_700_Host_Parameters *hostdata;
 
42
 
 
43
        if (!MACH_IS_MVME16x)
 
44
                goto out;
 
45
 
 
46
        if (mvme16x_config & MVME16x_CONFIG_NO_SCSICHIP) {
 
47
                printk(KERN_INFO "mvme16x-scsi: detection disabled, "
 
48
                                 "SCSI chip not present\n");
 
49
                goto out;
 
50
        }
 
51
 
 
52
        hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL);
 
53
        if (hostdata == NULL) {
 
54
                printk(KERN_ERR "mvme16x-scsi: "
 
55
                                "Failed to allocate host data\n");
 
56
                goto out;
 
57
        }
 
58
 
 
59
        /* Fill in the required pieces of hostdata */
 
60
        hostdata->base = (void __iomem *)0xfff47000UL;
 
61
        hostdata->clock = 50;   /* XXX - depends on the CPU clock! */
 
62
        hostdata->chip710 = 1;
 
63
        hostdata->dmode_extra = DMODE_FC2;
 
64
        hostdata->dcntl_extra = EA_710;
 
65
        hostdata->ctest7_extra = CTEST7_TT1;
 
66
 
 
67
        /* and register the chip */
 
68
        host = NCR_700_detect(&mvme16x_scsi_driver_template, hostdata,
 
69
                              &dev->dev);
 
70
        if (!host) {
 
71
                printk(KERN_ERR "mvme16x-scsi: No host detected; "
 
72
                                "board configuration problem?\n");
 
73
                goto out_free;
 
74
        }
 
75
        host->this_id = 7;
 
76
        host->base = 0xfff47000UL;
 
77
        host->irq = MVME16x_IRQ_SCSI;
 
78
        if (request_irq(host->irq, NCR_700_intr, 0, "mvme16x-scsi", host)) {
 
79
                printk(KERN_ERR "mvme16x-scsi: request_irq failed\n");
 
80
                goto out_put_host;
 
81
        }
 
82
 
 
83
        /* Enable scsi chip ints */
 
84
        {
 
85
                volatile unsigned long v;
 
86
 
 
87
                /* Enable scsi interrupts at level 4 in PCCchip2 */
 
88
                v = in_be32(0xfff4202c);
 
89
                v = (v & ~0xff) | 0x10 | 4;
 
90
                out_be32(0xfff4202c, v);
 
91
        }
 
92
 
 
93
        platform_set_drvdata(dev, host);
 
94
        scsi_scan_host(host);
 
95
 
 
96
        return 0;
 
97
 
 
98
 out_put_host:
 
99
        scsi_host_put(host);
 
100
 out_free:
 
101
        kfree(hostdata);
 
102
 out:
 
103
        return -ENODEV;
 
104
}
 
105
 
 
106
static __devexit int
 
107
mvme16x_device_remove(struct platform_device *dev)
 
108
{
 
109
        struct Scsi_Host *host = platform_get_drvdata(dev);
 
110
        struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
 
111
 
 
112
        /* Disable scsi chip ints */
 
113
        {
 
114
                volatile unsigned long v;
 
115
 
 
116
                v = in_be32(0xfff4202c);
 
117
                v &= ~0x10;
 
118
                out_be32(0xfff4202c, v);
 
119
        }
 
120
        scsi_remove_host(host);
 
121
        NCR_700_release(host);
 
122
        kfree(hostdata);
 
123
        free_irq(host->irq, host);
 
124
 
 
125
        return 0;
 
126
}
 
127
 
 
128
static struct platform_driver mvme16x_scsi_driver = {
 
129
        .driver = {
 
130
                .name           = "mvme16x-scsi",
 
131
                .owner          = THIS_MODULE,
 
132
        },
 
133
        .probe          = mvme16x_probe,
 
134
        .remove         = __devexit_p(mvme16x_device_remove),
 
135
};
 
136
 
 
137
static int __init mvme16x_scsi_init(void)
 
138
{
 
139
        int err;
 
140
 
 
141
        err = platform_driver_register(&mvme16x_scsi_driver);
 
142
        if (err)
 
143
                return err;
 
144
 
 
145
        mvme16x_scsi_device = platform_device_register_simple("mvme16x-scsi",
 
146
                                                              -1, NULL, 0);
 
147
        if (IS_ERR(mvme16x_scsi_device)) {
 
148
                platform_driver_unregister(&mvme16x_scsi_driver);
 
149
                return PTR_ERR(mvme16x_scsi_device);
 
150
        }
 
151
 
 
152
        return 0;
 
153
}
 
154
 
 
155
static void __exit mvme16x_scsi_exit(void)
 
156
{
 
157
        platform_device_unregister(mvme16x_scsi_device);
 
158
        platform_driver_unregister(&mvme16x_scsi_driver);
 
159
}
 
160
 
 
161
module_init(mvme16x_scsi_init);
 
162
module_exit(mvme16x_scsi_exit);