diff options
Diffstat (limited to 'drivers/scsi/sni_53c710.c')
-rw-r--r-- | drivers/scsi/sni_53c710.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c new file mode 100644 index 000000000000..6bc505115841 --- /dev/null +++ b/drivers/scsi/sni_53c710.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* -*- mode: c; c-basic-offset: 8 -*- */ | ||
2 | |||
3 | /* SNI RM driver | ||
4 | * | ||
5 | * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com | ||
6 | **----------------------------------------------------------------------------- | ||
7 | ** | ||
8 | ** This program is free software; you can redistribute it and/or modify | ||
9 | ** it under the terms of the GNU General Public License as published by | ||
10 | ** the Free Software Foundation; either version 2 of the License, or | ||
11 | ** (at your option) any later version. | ||
12 | ** | ||
13 | ** This program is distributed in the hope that it will be useful, | ||
14 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | ** GNU General Public License for more details. | ||
17 | ** | ||
18 | ** You should have received a copy of the GNU General Public License | ||
19 | ** along with this program; if not, write to the Free Software | ||
20 | ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | ** | ||
22 | **----------------------------------------------------------------------------- | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | * Based on lasi700.c | ||
27 | */ | ||
28 | |||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/types.h> | ||
33 | #include <linux/stat.h> | ||
34 | #include <linux/mm.h> | ||
35 | #include <linux/blkdev.h> | ||
36 | #include <linux/sched.h> | ||
37 | #include <linux/ioport.h> | ||
38 | #include <linux/dma-mapping.h> | ||
39 | #include <linux/platform_device.h> | ||
40 | |||
41 | #include <asm/page.h> | ||
42 | #include <asm/pgtable.h> | ||
43 | #include <asm/irq.h> | ||
44 | #include <asm/delay.h> | ||
45 | |||
46 | #include <scsi/scsi_host.h> | ||
47 | #include <scsi/scsi_device.h> | ||
48 | #include <scsi/scsi_transport.h> | ||
49 | #include <scsi/scsi_transport_spi.h> | ||
50 | |||
51 | #include "53c700.h" | ||
52 | |||
53 | MODULE_AUTHOR("Thomas Bogendörfer"); | ||
54 | MODULE_DESCRIPTION("SNI RM 53c710 SCSI Driver"); | ||
55 | MODULE_LICENSE("GPL"); | ||
56 | |||
57 | #define SNIRM710_CLOCK 32 | ||
58 | |||
59 | static struct scsi_host_template snirm710_template = { | ||
60 | .name = "SNI RM SCSI 53c710", | ||
61 | .proc_name = "snirm_53c710", | ||
62 | .this_id = 7, | ||
63 | .module = THIS_MODULE, | ||
64 | }; | ||
65 | |||
66 | static int __init snirm710_probe(struct platform_device *dev) | ||
67 | { | ||
68 | unsigned long base; | ||
69 | struct NCR_700_Host_Parameters *hostdata; | ||
70 | struct Scsi_Host *host; | ||
71 | struct resource *res; | ||
72 | |||
73 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
74 | if (!res) | ||
75 | return -ENODEV; | ||
76 | |||
77 | base = res->start; | ||
78 | hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); | ||
79 | if (!hostdata) { | ||
80 | printk(KERN_ERR "%s: Failed to allocate host data\n", | ||
81 | dev->dev.bus_id); | ||
82 | return -ENOMEM; | ||
83 | } | ||
84 | |||
85 | hostdata->dev = &dev->dev; | ||
86 | dma_set_mask(&dev->dev, DMA_32BIT_MASK); | ||
87 | hostdata->base = ioremap_nocache(CPHYSADDR(base), 0x100); | ||
88 | hostdata->differential = 0; | ||
89 | |||
90 | hostdata->clock = SNIRM710_CLOCK; | ||
91 | hostdata->force_le_on_be = 1; | ||
92 | hostdata->chip710 = 1; | ||
93 | hostdata->burst_length = 4; | ||
94 | |||
95 | host = NCR_700_detect(&snirm710_template, hostdata, &dev->dev); | ||
96 | if (!host) | ||
97 | goto out_kfree; | ||
98 | host->this_id = 7; | ||
99 | host->base = base; | ||
100 | host->irq = platform_get_irq(dev, 0); | ||
101 | if(request_irq(host->irq, NCR_700_intr, SA_SHIRQ, "snirm710", host)) { | ||
102 | printk(KERN_ERR "snirm710: request_irq failed!\n"); | ||
103 | goto out_put_host; | ||
104 | } | ||
105 | |||
106 | dev_set_drvdata(&dev->dev, host); | ||
107 | scsi_scan_host(host); | ||
108 | |||
109 | return 0; | ||
110 | |||
111 | out_put_host: | ||
112 | scsi_host_put(host); | ||
113 | out_kfree: | ||
114 | iounmap(hostdata->base); | ||
115 | kfree(hostdata); | ||
116 | return -ENODEV; | ||
117 | } | ||
118 | |||
119 | static int __exit snirm710_driver_remove(struct platform_device *dev) | ||
120 | { | ||
121 | struct Scsi_Host *host = dev_get_drvdata(&dev->dev); | ||
122 | struct NCR_700_Host_Parameters *hostdata = | ||
123 | (struct NCR_700_Host_Parameters *)host->hostdata[0]; | ||
124 | |||
125 | scsi_remove_host(host); | ||
126 | NCR_700_release(host); | ||
127 | free_irq(host->irq, host); | ||
128 | iounmap(hostdata->base); | ||
129 | kfree(hostdata); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static struct platform_driver snirm710_driver = { | ||
135 | .probe = snirm710_probe, | ||
136 | .remove = __devexit_p(snirm710_driver_remove), | ||
137 | .driver = { | ||
138 | .name = "snirm_53c710", | ||
139 | }, | ||
140 | }; | ||
141 | |||
142 | static int __init snirm710_init(void) | ||
143 | { | ||
144 | int err; | ||
145 | |||
146 | if ((err = platform_driver_register(&snirm710_driver))) { | ||
147 | printk(KERN_ERR "Driver registration failed\n"); | ||
148 | return err; | ||
149 | } | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static void __exit snirm710_exit(void) | ||
154 | { | ||
155 | platform_driver_unregister(&snirm710_driver); | ||
156 | } | ||
157 | |||
158 | module_init(snirm710_init); | ||
159 | module_exit(snirm710_exit); | ||