aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-27 13:19:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-27 13:19:19 -0400
commita9a0aff5b56d4c40288c000ff09c3f238b6b6fec (patch)
tree496cce8240689a61b4c76a4318ac53487287c74b /drivers
parentade61088bc77dd209f8edadbe544f1e5dad6c287 (diff)
parent0779c862e43e052c58a350a8bd2bf97e6908de04 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k: (24 commits) m68k: amiga - RTC platform device conversion m68k: amiga - Parallel port platform device conversion m68k: amiga - Serial port platform device conversion m68k: amiga - Mouse platform device conversion m68k: amiga - Keyboard platform device conversion m68k: amiga - Amiga Gayle IDE platform device conversion m68k: amiga - A4000T SCSI platform device conversion m68k/scsi: a3000 - Do not use legacy Scsi_Host.base m68k: amiga - A3000 SCSI platform device conversion m68k/scsi: gvp11 - Do not use legacy Scsi_Host.base m68k: amiga - GVP Series II SCSI zorro_driver conversion m68k/scsi: a2091 - Do not use legacy Scsi_Host.base m68k: amiga - A2091/A590 SCSI zorro_driver conversion m68k/scsi: mvme147 - Kill obsolete HOSTS_C logic m68k/scsi: a3000 - Kill a3000_scsiregs typedef m68k/scsi: gvp11 - Kill gvp11_scsiregs typedef m68k/scsi: a2091 - Kill a2091_scsiregs typedef m68k/scsi: gvp11 - Extract check_wd33c93() m68k/scsi: a3000 - Kill static global a3000_host m68k/scsi: mvme147 - Kill static global mvme147_host ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/amiserial.c61
-rw-r--r--drivers/ide/gayle.c147
-rw-r--r--drivers/input/keyboard/amikbd.c97
-rw-r--r--drivers/input/mouse/amimouse.c98
-rw-r--r--drivers/parport/parport_amiga.c64
-rw-r--r--drivers/scsi/a2091.c245
-rw-r--r--drivers/scsi/a2091.h4
-rw-r--r--drivers/scsi/a3000.c256
-rw-r--r--drivers/scsi/a3000.h4
-rw-r--r--drivers/scsi/a4000t.c101
-rw-r--r--drivers/scsi/gvp11.c541
-rw-r--r--drivers/scsi/gvp11.h11
-rw-r--r--drivers/scsi/mvme147.c33
13 files changed, 919 insertions, 743 deletions
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 56b27671adc4..4f8d60c25a98 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -84,6 +84,7 @@ static char *serial_version = "4.30";
84#include <linux/smp_lock.h> 84#include <linux/smp_lock.h>
85#include <linux/init.h> 85#include <linux/init.h>
86#include <linux/bitops.h> 86#include <linux/bitops.h>
87#include <linux/platform_device.h>
87 88
88#include <asm/setup.h> 89#include <asm/setup.h>
89 90
@@ -1954,29 +1955,16 @@ static const struct tty_operations serial_ops = {
1954/* 1955/*
1955 * The serial driver boot-time initialization code! 1956 * The serial driver boot-time initialization code!
1956 */ 1957 */
1957static int __init rs_init(void) 1958static int __init amiga_serial_probe(struct platform_device *pdev)
1958{ 1959{
1959 unsigned long flags; 1960 unsigned long flags;
1960 struct serial_state * state; 1961 struct serial_state * state;
1961 int error; 1962 int error;
1962 1963
1963 if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_SERIAL))
1964 return -ENODEV;
1965
1966 serial_driver = alloc_tty_driver(1); 1964 serial_driver = alloc_tty_driver(1);
1967 if (!serial_driver) 1965 if (!serial_driver)
1968 return -ENOMEM; 1966 return -ENOMEM;
1969 1967
1970 /*
1971 * We request SERDAT and SERPER only, because the serial registers are
1972 * too spreaded over the custom register space
1973 */
1974 if (!request_mem_region(CUSTOM_PHYSADDR+0x30, 4,
1975 "amiserial [Paula]")) {
1976 error = -EBUSY;
1977 goto fail_put_tty_driver;
1978 }
1979
1980 IRQ_ports = NULL; 1968 IRQ_ports = NULL;
1981 1969
1982 show_serial_version(); 1970 show_serial_version();
@@ -1998,7 +1986,7 @@ static int __init rs_init(void)
1998 1986
1999 error = tty_register_driver(serial_driver); 1987 error = tty_register_driver(serial_driver);
2000 if (error) 1988 if (error)
2001 goto fail_release_mem_region; 1989 goto fail_put_tty_driver;
2002 1990
2003 state = rs_table; 1991 state = rs_table;
2004 state->magic = SSTATE_MAGIC; 1992 state->magic = SSTATE_MAGIC;
@@ -2050,23 +2038,24 @@ static int __init rs_init(void)
2050 ciab.ddra |= (SER_DTR | SER_RTS); /* outputs */ 2038 ciab.ddra |= (SER_DTR | SER_RTS); /* outputs */
2051 ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */ 2039 ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */
2052 2040
2041 platform_set_drvdata(pdev, state);
2042
2053 return 0; 2043 return 0;
2054 2044
2055fail_free_irq: 2045fail_free_irq:
2056 free_irq(IRQ_AMIGA_TBE, state); 2046 free_irq(IRQ_AMIGA_TBE, state);
2057fail_unregister: 2047fail_unregister:
2058 tty_unregister_driver(serial_driver); 2048 tty_unregister_driver(serial_driver);
2059fail_release_mem_region:
2060 release_mem_region(CUSTOM_PHYSADDR+0x30, 4);
2061fail_put_tty_driver: 2049fail_put_tty_driver:
2062 put_tty_driver(serial_driver); 2050 put_tty_driver(serial_driver);
2063 return error; 2051 return error;
2064} 2052}
2065 2053
2066static __exit void rs_exit(void) 2054static int __exit amiga_serial_remove(struct platform_device *pdev)
2067{ 2055{
2068 int error; 2056 int error;
2069 struct async_struct *info = rs_table[0].info; 2057 struct serial_state *state = platform_get_drvdata(pdev);
2058 struct async_struct *info = state->info;
2070 2059
2071 /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ 2060 /* printk("Unloading %s: version %s\n", serial_name, serial_version); */
2072 tasklet_kill(&info->tlet); 2061 tasklet_kill(&info->tlet);
@@ -2075,19 +2064,38 @@ static __exit void rs_exit(void)
2075 error); 2064 error);
2076 put_tty_driver(serial_driver); 2065 put_tty_driver(serial_driver);
2077 2066
2078 if (info) { 2067 rs_table[0].info = NULL;
2079 rs_table[0].info = NULL; 2068 kfree(info);
2080 kfree(info);
2081 }
2082 2069
2083 free_irq(IRQ_AMIGA_TBE, rs_table); 2070 free_irq(IRQ_AMIGA_TBE, rs_table);
2084 free_irq(IRQ_AMIGA_RBF, rs_table); 2071 free_irq(IRQ_AMIGA_RBF, rs_table);
2085 2072
2086 release_mem_region(CUSTOM_PHYSADDR+0x30, 4); 2073 platform_set_drvdata(pdev, NULL);
2074
2075 return error;
2076}
2077
2078static struct platform_driver amiga_serial_driver = {
2079 .remove = __exit_p(amiga_serial_remove),
2080 .driver = {
2081 .name = "amiga-serial",
2082 .owner = THIS_MODULE,
2083 },
2084};
2085
2086static int __init amiga_serial_init(void)
2087{
2088 return platform_driver_probe(&amiga_serial_driver, amiga_serial_probe);
2089}
2090
2091module_init(amiga_serial_init);
2092
2093static void __exit amiga_serial_exit(void)
2094{
2095 platform_driver_unregister(&amiga_serial_driver);
2087} 2096}
2088 2097
2089module_init(rs_init) 2098module_exit(amiga_serial_exit);
2090module_exit(rs_exit)
2091 2099
2092 2100
2093#if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE) 2101#if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE)
@@ -2154,3 +2162,4 @@ console_initcall(amiserial_console_init);
2154#endif /* CONFIG_SERIAL_CONSOLE && !MODULE */ 2162#endif /* CONFIG_SERIAL_CONSOLE && !MODULE */
2155 2163
2156MODULE_LICENSE("GPL"); 2164MODULE_LICENSE("GPL");
2165MODULE_ALIAS("platform:amiga-serial");
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index b9e517de6a82..3feaa26410be 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/zorro.h> 17#include <linux/zorro.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/platform_device.h>
19 20
20#include <asm/setup.h> 21#include <asm/setup.h>
21#include <asm/amigahw.h> 22#include <asm/amigahw.h>
@@ -24,15 +25,6 @@
24 25
25 26
26 /* 27 /*
27 * Bases of the IDE interfaces
28 */
29
30#define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */
31#define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */
32
33#define GAYLE_IDEREG_SIZE 0x2000
34
35 /*
36 * Offsets from one of the above bases 28 * Offsets from one of the above bases
37 */ 29 */
38 30
@@ -68,20 +60,20 @@ MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
68 60
69static int gayle_test_irq(ide_hwif_t *hwif) 61static int gayle_test_irq(ide_hwif_t *hwif)
70{ 62{
71 unsigned char ch; 63 unsigned char ch;
72 64
73 ch = z_readb(hwif->io_ports.irq_addr); 65 ch = z_readb(hwif->io_ports.irq_addr);
74 if (!(ch & GAYLE_IRQ_IDE)) 66 if (!(ch & GAYLE_IRQ_IDE))
75 return 0; 67 return 0;
76 return 1; 68 return 1;
77} 69}
78 70
79static void gayle_a1200_clear_irq(ide_drive_t *drive) 71static void gayle_a1200_clear_irq(ide_drive_t *drive)
80{ 72{
81 ide_hwif_t *hwif = drive->hwif; 73 ide_hwif_t *hwif = drive->hwif;
82 74
83 (void)z_readb(hwif->io_ports.status_addr); 75 (void)z_readb(hwif->io_ports.status_addr);
84 z_writeb(0x7c, hwif->io_ports.irq_addr); 76 z_writeb(0x7c, hwif->io_ports.irq_addr);
85} 77}
86 78
87static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base, 79static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base,
@@ -122,64 +114,89 @@ static const struct ide_port_info gayle_port_info = {
122 * Probe for a Gayle IDE interface (and optionally for an IDE doubler) 114 * Probe for a Gayle IDE interface (and optionally for an IDE doubler)
123 */ 115 */
124 116
125static int __init gayle_init(void) 117static int __init amiga_gayle_ide_probe(struct platform_device *pdev)
126{ 118{
127 unsigned long phys_base, res_start, res_n; 119 struct resource *res;
128 unsigned long base, ctrlport, irqport; 120 struct gayle_ide_platform_data *pdata;
129 int a4000, i, rc; 121 unsigned long base, ctrlport, irqport;
130 struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS]; 122 unsigned int i;
131 struct ide_port_info d = gayle_port_info; 123 int error;
132 124 struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS];
133 if (!MACH_IS_AMIGA) 125 struct ide_port_info d = gayle_port_info;
134 return -ENODEV; 126 struct ide_host *host;
135 127
136 if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) 128 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
137 goto found; 129 if (!res)
138 130 return -ENODEV;
139#ifdef CONFIG_ZORRO 131
140 if (zorro_find_device(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE, 132 if (!request_mem_region(res->start, resource_size(res), "IDE"))
141 NULL)) 133 return -EBUSY;
142 goto found; 134
143#endif 135 pdata = pdev->dev.platform_data;
144 return -ENODEV; 136 pr_info("ide: Gayle IDE controller (A%u style%s)\n",
145 137 pdata->explicit_ack ? 1200 : 4000,
146found: 138 ide_doubler ? ", IDE doubler" : "");
147 printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n", 139
148 a4000 ? 4000 : 1200, 140 base = (unsigned long)ZTWO_VADDR(pdata->base);
149 ide_doubler ? ", IDE doubler" : ""); 141 ctrlport = 0;
150 142 irqport = (unsigned long)ZTWO_VADDR(pdata->irqport);
151 if (a4000) { 143 if (pdata->explicit_ack)
152 phys_base = GAYLE_BASE_4000; 144 d.port_ops = &gayle_a1200_port_ops;
153 irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000); 145 else
154 d.port_ops = &gayle_a4000_port_ops; 146 d.port_ops = &gayle_a4000_port_ops;
155 } else { 147
156 phys_base = GAYLE_BASE_1200; 148 for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++, base += GAYLE_NEXT_PORT) {
157 irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200); 149 if (GAYLE_HAS_CONTROL_REG)
158 d.port_ops = &gayle_a1200_port_ops; 150 ctrlport = base + GAYLE_CONTROL;
151
152 gayle_setup_ports(&hw[i], base, ctrlport, irqport);
153 hws[i] = &hw[i];
159 } 154 }
160 155
161 res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); 156 error = ide_host_add(&d, hws, i, &host);
162 res_n = GAYLE_IDEREG_SIZE; 157 if (error)
158 goto out;
163 159
164 if (!request_mem_region(res_start, res_n, "IDE")) 160 platform_set_drvdata(pdev, host);
165 return -EBUSY; 161 return 0;
166 162
167 for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { 163out:
168 base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT); 164 release_mem_region(res->start, resource_size(res));
169 ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; 165 return error;
166}
167
168static int __exit amiga_gayle_ide_remove(struct platform_device *pdev)
169{
170 struct ide_host *host = platform_get_drvdata(pdev);
171 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
172
173 ide_host_remove(host);
174 release_mem_region(res->start, resource_size(res));
175 return 0;
176}
170 177
171 gayle_setup_ports(&hw[i], base, ctrlport, irqport); 178static struct platform_driver amiga_gayle_ide_driver = {
179 .remove = __exit_p(amiga_gayle_ide_remove),
180 .driver = {
181 .name = "amiga-gayle-ide",
182 .owner = THIS_MODULE,
183 },
184};
172 185
173 hws[i] = &hw[i]; 186static int __init amiga_gayle_ide_init(void)
174 } 187{
188 return platform_driver_probe(&amiga_gayle_ide_driver,
189 amiga_gayle_ide_probe);
190}
175 191
176 rc = ide_host_add(&d, hws, i, NULL); 192module_init(amiga_gayle_ide_init);
177 if (rc)
178 release_mem_region(res_start, res_n);
179 193
180 return rc; 194static void __exit amiga_gayle_ide_exit(void)
195{
196 platform_driver_unregister(&amiga_gayle_ide_driver);
181} 197}
182 198
183module_init(gayle_init); 199module_exit(amiga_gayle_ide_exit);
184 200
185MODULE_LICENSE("GPL"); 201MODULE_LICENSE("GPL");
202MODULE_ALIAS("platform:amiga-gayle-ide");
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 35149ec455a9..79172af164f2 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -35,6 +35,7 @@
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/keyboard.h> 37#include <linux/keyboard.h>
38#include <linux/platform_device.h>
38 39
39#include <asm/amigaints.h> 40#include <asm/amigaints.h>
40#include <asm/amigahw.h> 41#include <asm/amigahw.h>
@@ -154,10 +155,9 @@ static const char *amikbd_messages[8] = {
154 [7] = KERN_WARNING "amikbd: keyboard interrupt\n" 155 [7] = KERN_WARNING "amikbd: keyboard interrupt\n"
155}; 156};
156 157
157static struct input_dev *amikbd_dev; 158static irqreturn_t amikbd_interrupt(int irq, void *data)
158
159static irqreturn_t amikbd_interrupt(int irq, void *dummy)
160{ 159{
160 struct input_dev *dev = data;
161 unsigned char scancode, down; 161 unsigned char scancode, down;
162 162
163 scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */ 163 scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */
@@ -170,47 +170,42 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy)
170 170
171 if (scancode < 0x78) { /* scancodes < 0x78 are keys */ 171 if (scancode < 0x78) { /* scancodes < 0x78 are keys */
172 if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ 172 if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */
173 input_report_key(amikbd_dev, scancode, 1); 173 input_report_key(dev, scancode, 1);
174 input_report_key(amikbd_dev, scancode, 0); 174 input_report_key(dev, scancode, 0);
175 } else { 175 } else {
176 input_report_key(amikbd_dev, scancode, down); 176 input_report_key(dev, scancode, down);
177 } 177 }
178 178
179 input_sync(amikbd_dev); 179 input_sync(dev);
180 } else /* scancodes >= 0x78 are error codes */ 180 } else /* scancodes >= 0x78 are error codes */
181 printk(amikbd_messages[scancode - 0x78]); 181 printk(amikbd_messages[scancode - 0x78]);
182 182
183 return IRQ_HANDLED; 183 return IRQ_HANDLED;
184} 184}
185 185
186static int __init amikbd_init(void) 186static int __init amikbd_probe(struct platform_device *pdev)
187{ 187{
188 struct input_dev *dev;
188 int i, j, err; 189 int i, j, err;
189 190
190 if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) 191 dev = input_allocate_device();
191 return -ENODEV; 192 if (!dev) {
192 193 dev_err(&pdev->dev, "Not enough memory for input device\n");
193 if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) 194 return -ENOMEM;
194 return -EBUSY;
195
196 amikbd_dev = input_allocate_device();
197 if (!amikbd_dev) {
198 printk(KERN_ERR "amikbd: not enough memory for input device\n");
199 err = -ENOMEM;
200 goto fail1;
201 } 195 }
202 196
203 amikbd_dev->name = "Amiga Keyboard"; 197 dev->name = pdev->name;
204 amikbd_dev->phys = "amikbd/input0"; 198 dev->phys = "amikbd/input0";
205 amikbd_dev->id.bustype = BUS_AMIGA; 199 dev->id.bustype = BUS_AMIGA;
206 amikbd_dev->id.vendor = 0x0001; 200 dev->id.vendor = 0x0001;
207 amikbd_dev->id.product = 0x0001; 201 dev->id.product = 0x0001;
208 amikbd_dev->id.version = 0x0100; 202 dev->id.version = 0x0100;
203 dev->dev.parent = &pdev->dev;
209 204
210 amikbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); 205 dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
211 206
212 for (i = 0; i < 0x78; i++) 207 for (i = 0; i < 0x78; i++)
213 set_bit(i, amikbd_dev->keybit); 208 set_bit(i, dev->keybit);
214 209
215 for (i = 0; i < MAX_NR_KEYMAPS; i++) { 210 for (i = 0; i < MAX_NR_KEYMAPS; i++) {
216 static u_short temp_map[NR_KEYS] __initdata; 211 static u_short temp_map[NR_KEYS] __initdata;
@@ -229,30 +224,54 @@ static int __init amikbd_init(void)
229 memcpy(key_maps[i], temp_map, sizeof(temp_map)); 224 memcpy(key_maps[i], temp_map, sizeof(temp_map));
230 } 225 }
231 ciaa.cra &= ~0x41; /* serial data in, turn off TA */ 226 ciaa.cra &= ~0x41; /* serial data in, turn off TA */
232 if (request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", 227 err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd",
233 amikbd_interrupt)) { 228 dev);
234 err = -EBUSY; 229 if (err)
235 goto fail2; 230 goto fail2;
236 }
237 231
238 err = input_register_device(amikbd_dev); 232 err = input_register_device(dev);
239 if (err) 233 if (err)
240 goto fail3; 234 goto fail3;
241 235
236 platform_set_drvdata(pdev, dev);
237
242 return 0; 238 return 0;
243 239
244 fail3: free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); 240 fail3: free_irq(IRQ_AMIGA_CIAA_SP, dev);
245 fail2: input_free_device(amikbd_dev); 241 fail2: input_free_device(dev);
246 fail1: release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
247 return err; 242 return err;
248} 243}
249 244
250static void __exit amikbd_exit(void) 245static int __exit amikbd_remove(struct platform_device *pdev)
246{
247 struct input_dev *dev = platform_get_drvdata(pdev);
248
249 platform_set_drvdata(pdev, NULL);
250 free_irq(IRQ_AMIGA_CIAA_SP, dev);
251 input_unregister_device(dev);
252 return 0;
253}
254
255static struct platform_driver amikbd_driver = {
256 .remove = __exit_p(amikbd_remove),
257 .driver = {
258 .name = "amiga-keyboard",
259 .owner = THIS_MODULE,
260 },
261};
262
263static int __init amikbd_init(void)
251{ 264{
252 free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); 265 return platform_driver_probe(&amikbd_driver, amikbd_probe);
253 input_unregister_device(amikbd_dev);
254 release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
255} 266}
256 267
257module_init(amikbd_init); 268module_init(amikbd_init);
269
270static void __exit amikbd_exit(void)
271{
272 platform_driver_unregister(&amikbd_driver);
273}
274
258module_exit(amikbd_exit); 275module_exit(amikbd_exit);
276
277MODULE_ALIAS("platform:amiga-keyboard");
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
index a185ac78a42c..ff5f61a0fd3a 100644
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -21,6 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/irq.h> 26#include <asm/irq.h>
26#include <asm/setup.h> 27#include <asm/setup.h>
@@ -34,10 +35,10 @@ MODULE_DESCRIPTION("Amiga mouse driver");
34MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
35 36
36static int amimouse_lastx, amimouse_lasty; 37static int amimouse_lastx, amimouse_lasty;
37static struct input_dev *amimouse_dev;
38 38
39static irqreturn_t amimouse_interrupt(int irq, void *dummy) 39static irqreturn_t amimouse_interrupt(int irq, void *data)
40{ 40{
41 struct input_dev *dev = data;
41 unsigned short joy0dat, potgor; 42 unsigned short joy0dat, potgor;
42 int nx, ny, dx, dy; 43 int nx, ny, dx, dy;
43 44
@@ -59,14 +60,14 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy)
59 60
60 potgor = amiga_custom.potgor; 61 potgor = amiga_custom.potgor;
61 62
62 input_report_rel(amimouse_dev, REL_X, dx); 63 input_report_rel(dev, REL_X, dx);
63 input_report_rel(amimouse_dev, REL_Y, dy); 64 input_report_rel(dev, REL_Y, dy);
64 65
65 input_report_key(amimouse_dev, BTN_LEFT, ciaa.pra & 0x40); 66 input_report_key(dev, BTN_LEFT, ciaa.pra & 0x40);
66 input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100); 67 input_report_key(dev, BTN_MIDDLE, potgor & 0x0100);
67 input_report_key(amimouse_dev, BTN_RIGHT, potgor & 0x0400); 68 input_report_key(dev, BTN_RIGHT, potgor & 0x0400);
68 69
69 input_sync(amimouse_dev); 70 input_sync(dev);
70 71
71 return IRQ_HANDLED; 72 return IRQ_HANDLED;
72} 73}
@@ -74,63 +75,90 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy)
74static int amimouse_open(struct input_dev *dev) 75static int amimouse_open(struct input_dev *dev)
75{ 76{
76 unsigned short joy0dat; 77 unsigned short joy0dat;
78 int error;
77 79
78 joy0dat = amiga_custom.joy0dat; 80 joy0dat = amiga_custom.joy0dat;
79 81
80 amimouse_lastx = joy0dat & 0xff; 82 amimouse_lastx = joy0dat & 0xff;
81 amimouse_lasty = joy0dat >> 8; 83 amimouse_lasty = joy0dat >> 8;
82 84
83 if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) { 85 error = request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse",
84 printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB); 86 dev);
85 return -EBUSY; 87 if (error)
86 } 88 dev_err(&dev->dev, "Can't allocate irq %d\n", IRQ_AMIGA_VERTB);
87 89
88 return 0; 90 return error;
89} 91}
90 92
91static void amimouse_close(struct input_dev *dev) 93static void amimouse_close(struct input_dev *dev)
92{ 94{
93 free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt); 95 free_irq(IRQ_AMIGA_VERTB, dev);
94} 96}
95 97
96static int __init amimouse_init(void) 98static int __init amimouse_probe(struct platform_device *pdev)
97{ 99{
98 int err; 100 int err;
101 struct input_dev *dev;
99 102
100 if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) 103 dev = input_allocate_device();
101 return -ENODEV; 104 if (!dev)
102
103 amimouse_dev = input_allocate_device();
104 if (!amimouse_dev)
105 return -ENOMEM; 105 return -ENOMEM;
106 106
107 amimouse_dev->name = "Amiga mouse"; 107 dev->name = pdev->name;
108 amimouse_dev->phys = "amimouse/input0"; 108 dev->phys = "amimouse/input0";
109 amimouse_dev->id.bustype = BUS_AMIGA; 109 dev->id.bustype = BUS_AMIGA;
110 amimouse_dev->id.vendor = 0x0001; 110 dev->id.vendor = 0x0001;
111 amimouse_dev->id.product = 0x0002; 111 dev->id.product = 0x0002;
112 amimouse_dev->id.version = 0x0100; 112 dev->id.version = 0x0100;
113 113
114 amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); 114 dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
115 amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); 115 dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
116 amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | 116 dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
117 BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); 117 BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
118 amimouse_dev->open = amimouse_open; 118 dev->open = amimouse_open;
119 amimouse_dev->close = amimouse_close; 119 dev->close = amimouse_close;
120 dev->dev.parent = &pdev->dev;
120 121
121 err = input_register_device(amimouse_dev); 122 err = input_register_device(dev);
122 if (err) { 123 if (err) {
123 input_free_device(amimouse_dev); 124 input_free_device(dev);
124 return err; 125 return err;
125 } 126 }
126 127
128 platform_set_drvdata(pdev, dev);
129
127 return 0; 130 return 0;
128} 131}
129 132
130static void __exit amimouse_exit(void) 133static int __exit amimouse_remove(struct platform_device *pdev)
131{ 134{
132 input_unregister_device(amimouse_dev); 135 struct input_dev *dev = platform_get_drvdata(pdev);
136
137 platform_set_drvdata(pdev, NULL);
138 input_unregister_device(dev);
139 return 0;
140}
141
142static struct platform_driver amimouse_driver = {
143 .remove = __exit_p(amimouse_remove),
144 .driver = {
145 .name = "amiga-mouse",
146 .owner = THIS_MODULE,
147 },
148};
149
150static int __init amimouse_init(void)
151{
152 return platform_driver_probe(&amimouse_driver, amimouse_probe);
133} 153}
134 154
135module_init(amimouse_init); 155module_init(amimouse_init);
156
157static void __exit amimouse_exit(void)
158{
159 platform_driver_unregister(&amimouse_driver);
160}
161
136module_exit(amimouse_exit); 162module_exit(amimouse_exit);
163
164MODULE_ALIAS("platform:amiga-mouse");
diff --git a/drivers/parport/parport_amiga.c b/drivers/parport/parport_amiga.c
index 1586e1caa2f5..8bef6d60f88b 100644
--- a/drivers/parport/parport_amiga.c
+++ b/drivers/parport/parport_amiga.c
@@ -18,6 +18,8 @@
18#include <linux/parport.h> 18#include <linux/parport.h>
19#include <linux/ioport.h> 19#include <linux/ioport.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/platform_device.h>
22
21#include <asm/setup.h> 23#include <asm/setup.h>
22#include <asm/amigahw.h> 24#include <asm/amigahw.h>
23#include <asm/irq.h> 25#include <asm/irq.h>
@@ -31,7 +33,6 @@
31#define DPRINTK(x...) do { } while (0) 33#define DPRINTK(x...) do { } while (0)
32#endif 34#endif
33 35
34static struct parport *this_port = NULL;
35 36
36static void amiga_write_data(struct parport *p, unsigned char data) 37static void amiga_write_data(struct parport *p, unsigned char data)
37{ 38{
@@ -227,18 +228,11 @@ static struct parport_operations pp_amiga_ops = {
227 228
228/* ----------- Initialisation code --------------------------------- */ 229/* ----------- Initialisation code --------------------------------- */
229 230
230static int __init parport_amiga_init(void) 231static int __init amiga_parallel_probe(struct platform_device *pdev)
231{ 232{
232 struct parport *p; 233 struct parport *p;
233 int err; 234 int err;
234 235
235 if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_PARALLEL))
236 return -ENODEV;
237
238 err = -EBUSY;
239 if (!request_mem_region(CIAA_PHYSADDR-1+0x100, 0x100, "parallel"))
240 goto out_mem;
241
242 ciaa.ddrb = 0xff; 236 ciaa.ddrb = 0xff;
243 ciab.ddra &= 0xf8; 237 ciab.ddra &= 0xf8;
244 mb(); 238 mb();
@@ -246,41 +240,63 @@ static int __init parport_amiga_init(void)
246 p = parport_register_port((unsigned long)&ciaa.prb, IRQ_AMIGA_CIAA_FLG, 240 p = parport_register_port((unsigned long)&ciaa.prb, IRQ_AMIGA_CIAA_FLG,
247 PARPORT_DMA_NONE, &pp_amiga_ops); 241 PARPORT_DMA_NONE, &pp_amiga_ops);
248 if (!p) 242 if (!p)
249 goto out_port; 243 return -EBUSY;
250 244
251 err = request_irq(IRQ_AMIGA_CIAA_FLG, parport_irq_handler, 0, p->name, p); 245 err = request_irq(IRQ_AMIGA_CIAA_FLG, parport_irq_handler, 0, p->name,
246 p);
252 if (err) 247 if (err)
253 goto out_irq; 248 goto out_irq;
254 249
255 this_port = p;
256 printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name); 250 printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name);
257 /* XXX: set operating mode */ 251 /* XXX: set operating mode */
258 parport_announce_port(p); 252 parport_announce_port(p);
259 253
254 platform_set_drvdata(pdev, p);
255
260 return 0; 256 return 0;
261 257
262out_irq: 258out_irq:
263 parport_put_port(p); 259 parport_put_port(p);
264out_port:
265 release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100);
266out_mem:
267 return err; 260 return err;
268} 261}
269 262
270static void __exit parport_amiga_exit(void) 263static int __exit amiga_parallel_remove(struct platform_device *pdev)
264{
265 struct parport *port = platform_get_drvdata(pdev);
266
267 parport_remove_port(port);
268 if (port->irq != PARPORT_IRQ_NONE)
269 free_irq(IRQ_AMIGA_CIAA_FLG, port);
270 parport_put_port(port);
271 platform_set_drvdata(pdev, NULL);
272 return 0;
273}
274
275static struct platform_driver amiga_parallel_driver = {
276 .remove = __exit_p(amiga_parallel_remove),
277 .driver = {
278 .name = "amiga-parallel",
279 .owner = THIS_MODULE,
280 },
281};
282
283static int __init amiga_parallel_init(void)
284{
285 return platform_driver_probe(&amiga_parallel_driver,
286 amiga_parallel_probe);
287}
288
289module_init(amiga_parallel_init);
290
291static void __exit amiga_parallel_exit(void)
271{ 292{
272 parport_remove_port(this_port); 293 platform_driver_unregister(&amiga_parallel_driver);
273 if (this_port->irq != PARPORT_IRQ_NONE)
274 free_irq(IRQ_AMIGA_CIAA_FLG, this_port);
275 parport_put_port(this_port);
276 release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100);
277} 294}
278 295
296module_exit(amiga_parallel_exit);
279 297
280MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>"); 298MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
281MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port"); 299MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
282MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port"); 300MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
283MODULE_LICENSE("GPL"); 301MODULE_LICENSE("GPL");
284 302MODULE_ALIAS("platform:amiga-parallel");
285module_init(parport_amiga_init)
286module_exit(parport_amiga_exit)
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 308541ff85cf..1bb5d3f0e260 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -1,34 +1,31 @@
1#include <linux/types.h> 1#include <linux/types.h>
2#include <linux/mm.h>
3#include <linux/slab.h>
4#include <linux/blkdev.h>
5#include <linux/init.h> 2#include <linux/init.h>
6#include <linux/interrupt.h> 3#include <linux/interrupt.h>
4#include <linux/mm.h>
5#include <linux/slab.h>
6#include <linux/spinlock.h>
7#include <linux/zorro.h>
7 8
8#include <asm/setup.h>
9#include <asm/page.h> 9#include <asm/page.h>
10#include <asm/pgtable.h> 10#include <asm/pgtable.h>
11#include <asm/amigaints.h> 11#include <asm/amigaints.h>
12#include <asm/amigahw.h> 12#include <asm/amigahw.h>
13#include <linux/zorro.h>
14#include <asm/irq.h>
15#include <linux/spinlock.h>
16 13
17#include "scsi.h" 14#include "scsi.h"
18#include <scsi/scsi_host.h>
19#include "wd33c93.h" 15#include "wd33c93.h"
20#include "a2091.h" 16#include "a2091.h"
21 17
22#include <linux/stat.h>
23
24 18
25static int a2091_release(struct Scsi_Host *instance); 19struct a2091_hostdata {
20 struct WD33C93_hostdata wh;
21 struct a2091_scsiregs *regs;
22};
26 23
27static irqreturn_t a2091_intr(int irq, void *data) 24static irqreturn_t a2091_intr(int irq, void *data)
28{ 25{
29 struct Scsi_Host *instance = data; 26 struct Scsi_Host *instance = data;
30 a2091_scsiregs *regs = (a2091_scsiregs *)(instance->base); 27 struct a2091_hostdata *hdata = shost_priv(instance);
31 unsigned int status = regs->ISTR; 28 unsigned int status = hdata->regs->ISTR;
32 unsigned long flags; 29 unsigned long flags;
33 30
34 if (!(status & (ISTR_INT_F | ISTR_INT_P)) || !(status & ISTR_INTS)) 31 if (!(status & (ISTR_INT_F | ISTR_INT_P)) || !(status & ISTR_INTS))
@@ -43,38 +40,39 @@ static irqreturn_t a2091_intr(int irq, void *data)
43static int dma_setup(struct scsi_cmnd *cmd, int dir_in) 40static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
44{ 41{
45 struct Scsi_Host *instance = cmd->device->host; 42 struct Scsi_Host *instance = cmd->device->host;
46 struct WD33C93_hostdata *hdata = shost_priv(instance); 43 struct a2091_hostdata *hdata = shost_priv(instance);
47 a2091_scsiregs *regs = (a2091_scsiregs *)(instance->base); 44 struct WD33C93_hostdata *wh = &hdata->wh;
45 struct a2091_scsiregs *regs = hdata->regs;
48 unsigned short cntr = CNTR_PDMD | CNTR_INTEN; 46 unsigned short cntr = CNTR_PDMD | CNTR_INTEN;
49 unsigned long addr = virt_to_bus(cmd->SCp.ptr); 47 unsigned long addr = virt_to_bus(cmd->SCp.ptr);
50 48
51 /* don't allow DMA if the physical address is bad */ 49 /* don't allow DMA if the physical address is bad */
52 if (addr & A2091_XFER_MASK) { 50 if (addr & A2091_XFER_MASK) {
53 hdata->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; 51 wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff;
54 hdata->dma_bounce_buffer = kmalloc(hdata->dma_bounce_len, 52 wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len,
55 GFP_KERNEL); 53 GFP_KERNEL);
56 54
57 /* can't allocate memory; use PIO */ 55 /* can't allocate memory; use PIO */
58 if (!hdata->dma_bounce_buffer) { 56 if (!wh->dma_bounce_buffer) {
59 hdata->dma_bounce_len = 0; 57 wh->dma_bounce_len = 0;
60 return 1; 58 return 1;
61 } 59 }
62 60
63 /* get the physical address of the bounce buffer */ 61 /* get the physical address of the bounce buffer */
64 addr = virt_to_bus(hdata->dma_bounce_buffer); 62 addr = virt_to_bus(wh->dma_bounce_buffer);
65 63
66 /* the bounce buffer may not be in the first 16M of physmem */ 64 /* the bounce buffer may not be in the first 16M of physmem */
67 if (addr & A2091_XFER_MASK) { 65 if (addr & A2091_XFER_MASK) {
68 /* we could use chipmem... maybe later */ 66 /* we could use chipmem... maybe later */
69 kfree(hdata->dma_bounce_buffer); 67 kfree(wh->dma_bounce_buffer);
70 hdata->dma_bounce_buffer = NULL; 68 wh->dma_bounce_buffer = NULL;
71 hdata->dma_bounce_len = 0; 69 wh->dma_bounce_len = 0;
72 return 1; 70 return 1;
73 } 71 }
74 72
75 if (!dir_in) { 73 if (!dir_in) {
76 /* copy to bounce buffer for a write */ 74 /* copy to bounce buffer for a write */
77 memcpy(hdata->dma_bounce_buffer, cmd->SCp.ptr, 75 memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr,
78 cmd->SCp.this_residual); 76 cmd->SCp.this_residual);
79 } 77 }
80 } 78 }
@@ -84,7 +82,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
84 cntr |= CNTR_DDIR; 82 cntr |= CNTR_DDIR;
85 83
86 /* remember direction */ 84 /* remember direction */
87 hdata->dma_dir = dir_in; 85 wh->dma_dir = dir_in;
88 86
89 regs->CNTR = cntr; 87 regs->CNTR = cntr;
90 88
@@ -108,20 +106,21 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
108static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, 106static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
109 int status) 107 int status)
110{ 108{
111 struct WD33C93_hostdata *hdata = shost_priv(instance); 109 struct a2091_hostdata *hdata = shost_priv(instance);
112 a2091_scsiregs *regs = (a2091_scsiregs *)(instance->base); 110 struct WD33C93_hostdata *wh = &hdata->wh;
111 struct a2091_scsiregs *regs = hdata->regs;
113 112
114 /* disable SCSI interrupts */ 113 /* disable SCSI interrupts */
115 unsigned short cntr = CNTR_PDMD; 114 unsigned short cntr = CNTR_PDMD;
116 115
117 if (!hdata->dma_dir) 116 if (!wh->dma_dir)
118 cntr |= CNTR_DDIR; 117 cntr |= CNTR_DDIR;
119 118
120 /* disable SCSI interrupts */ 119 /* disable SCSI interrupts */
121 regs->CNTR = cntr; 120 regs->CNTR = cntr;
122 121
123 /* flush if we were reading */ 122 /* flush if we were reading */
124 if (hdata->dma_dir) { 123 if (wh->dma_dir) {
125 regs->FLUSH = 1; 124 regs->FLUSH = 1;
126 while (!(regs->ISTR & ISTR_FE_FLG)) 125 while (!(regs->ISTR & ISTR_FE_FLG))
127 ; 126 ;
@@ -137,95 +136,37 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
137 regs->CNTR = CNTR_PDMD | CNTR_INTEN; 136 regs->CNTR = CNTR_PDMD | CNTR_INTEN;
138 137
139 /* copy from a bounce buffer, if necessary */ 138 /* copy from a bounce buffer, if necessary */
140 if (status && hdata->dma_bounce_buffer) { 139 if (status && wh->dma_bounce_buffer) {
141 if (hdata->dma_dir) 140 if (wh->dma_dir)
142 memcpy(SCpnt->SCp.ptr, hdata->dma_bounce_buffer, 141 memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer,
143 SCpnt->SCp.this_residual); 142 SCpnt->SCp.this_residual);
144 kfree(hdata->dma_bounce_buffer); 143 kfree(wh->dma_bounce_buffer);
145 hdata->dma_bounce_buffer = NULL; 144 wh->dma_bounce_buffer = NULL;
146 hdata->dma_bounce_len = 0; 145 wh->dma_bounce_len = 0;
147 }
148}
149
150static int __init a2091_detect(struct scsi_host_template *tpnt)
151{
152 static unsigned char called = 0;
153 struct Scsi_Host *instance;
154 unsigned long address;
155 struct zorro_dev *z = NULL;
156 wd33c93_regs wdregs;
157 a2091_scsiregs *regs;
158 struct WD33C93_hostdata *hdata;
159 int num_a2091 = 0;
160
161 if (!MACH_IS_AMIGA || called)
162 return 0;
163 called = 1;
164
165 tpnt->proc_name = "A2091";
166 tpnt->proc_info = &wd33c93_proc_info;
167
168 while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
169 if (z->id != ZORRO_PROD_CBM_A590_A2091_1 &&
170 z->id != ZORRO_PROD_CBM_A590_A2091_2)
171 continue;
172 address = z->resource.start;
173 if (!request_mem_region(address, 256, "wd33c93"))
174 continue;
175
176 instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
177 if (instance == NULL)
178 goto release;
179 instance->base = ZTWO_VADDR(address);
180 instance->irq = IRQ_AMIGA_PORTS;
181 instance->unique_id = z->slotaddr;
182 regs = (a2091_scsiregs *)(instance->base);
183 regs->DAWR = DAWR_A2091;
184 wdregs.SASR = &regs->SASR;
185 wdregs.SCMD = &regs->SCMD;
186 hdata = shost_priv(instance);
187 hdata->no_sync = 0xff;
188 hdata->fast = 0;
189 hdata->dma_mode = CTRL_DMA;
190 wd33c93_init(instance, wdregs, dma_setup, dma_stop,
191 WD33C93_FS_8_10);
192 if (request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED,
193 "A2091 SCSI", instance))
194 goto unregister;
195 regs->CNTR = CNTR_PDMD | CNTR_INTEN;
196 num_a2091++;
197 continue;
198
199unregister:
200 scsi_unregister(instance);
201release:
202 release_mem_region(address, 256);
203 } 146 }
204
205 return num_a2091;
206} 147}
207 148
208static int a2091_bus_reset(struct scsi_cmnd *cmd) 149static int a2091_bus_reset(struct scsi_cmnd *cmd)
209{ 150{
151 struct Scsi_Host *instance = cmd->device->host;
152
210 /* FIXME perform bus-specific reset */ 153 /* FIXME perform bus-specific reset */
211 154
212 /* FIXME 2: kill this function, and let midlayer fall back 155 /* FIXME 2: kill this function, and let midlayer fall back
213 to the same action, calling wd33c93_host_reset() */ 156 to the same action, calling wd33c93_host_reset() */
214 157
215 spin_lock_irq(cmd->device->host->host_lock); 158 spin_lock_irq(instance->host_lock);
216 wd33c93_host_reset(cmd); 159 wd33c93_host_reset(cmd);
217 spin_unlock_irq(cmd->device->host->host_lock); 160 spin_unlock_irq(instance->host_lock);
218 161
219 return SUCCESS; 162 return SUCCESS;
220} 163}
221 164
222#define HOSTS_C 165static struct scsi_host_template a2091_scsi_template = {
223 166 .module = THIS_MODULE,
224static struct scsi_host_template driver_template = {
225 .proc_name = "A2901",
226 .name = "Commodore A2091/A590 SCSI", 167 .name = "Commodore A2091/A590 SCSI",
227 .detect = a2091_detect, 168 .proc_info = wd33c93_proc_info,
228 .release = a2091_release, 169 .proc_name = "A2901",
229 .queuecommand = wd33c93_queuecommand, 170 .queuecommand = wd33c93_queuecommand,
230 .eh_abort_handler = wd33c93_abort, 171 .eh_abort_handler = wd33c93_abort,
231 .eh_bus_reset_handler = a2091_bus_reset, 172 .eh_bus_reset_handler = a2091_bus_reset,
@@ -237,19 +178,103 @@ static struct scsi_host_template driver_template = {
237 .use_clustering = DISABLE_CLUSTERING 178 .use_clustering = DISABLE_CLUSTERING
238}; 179};
239 180
181static int __devinit a2091_probe(struct zorro_dev *z,
182 const struct zorro_device_id *ent)
183{
184 struct Scsi_Host *instance;
185 int error;
186 struct a2091_scsiregs *regs;
187 wd33c93_regs wdregs;
188 struct a2091_hostdata *hdata;
240 189
241#include "scsi_module.c" 190 if (!request_mem_region(z->resource.start, 256, "wd33c93"))
191 return -EBUSY;
242 192
243static int a2091_release(struct Scsi_Host *instance) 193 instance = scsi_host_alloc(&a2091_scsi_template,
194 sizeof(struct a2091_hostdata));
195 if (!instance) {
196 error = -ENOMEM;
197 goto fail_alloc;
198 }
199
200 instance->irq = IRQ_AMIGA_PORTS;
201 instance->unique_id = z->slotaddr;
202
203 regs = (struct a2091_scsiregs *)ZTWO_VADDR(z->resource.start);
204 regs->DAWR = DAWR_A2091;
205
206 wdregs.SASR = &regs->SASR;
207 wdregs.SCMD = &regs->SCMD;
208
209 hdata = shost_priv(instance);
210 hdata->wh.no_sync = 0xff;
211 hdata->wh.fast = 0;
212 hdata->wh.dma_mode = CTRL_DMA;
213 hdata->regs = regs;
214
215 wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_8_10);
216 error = request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED,
217 "A2091 SCSI", instance);
218 if (error)
219 goto fail_irq;
220
221 regs->CNTR = CNTR_PDMD | CNTR_INTEN;
222
223 error = scsi_add_host(instance, NULL);
224 if (error)
225 goto fail_host;
226
227 zorro_set_drvdata(z, instance);
228
229 scsi_scan_host(instance);
230 return 0;
231
232fail_host:
233 free_irq(IRQ_AMIGA_PORTS, instance);
234fail_irq:
235 scsi_host_put(instance);
236fail_alloc:
237 release_mem_region(z->resource.start, 256);
238 return error;
239}
240
241static void __devexit a2091_remove(struct zorro_dev *z)
244{ 242{
245#ifdef MODULE 243 struct Scsi_Host *instance = zorro_get_drvdata(z);
246 a2091_scsiregs *regs = (a2091_scsiregs *)(instance->base); 244 struct a2091_hostdata *hdata = shost_priv(instance);
247 245
248 regs->CNTR = 0; 246 hdata->regs->CNTR = 0;
249 release_mem_region(ZTWO_PADDR(instance->base), 256); 247 scsi_remove_host(instance);
250 free_irq(IRQ_AMIGA_PORTS, instance); 248 free_irq(IRQ_AMIGA_PORTS, instance);
251#endif 249 scsi_host_put(instance);
252 return 1; 250 release_mem_region(z->resource.start, 256);
251}
252
253static struct zorro_device_id a2091_zorro_tbl[] __devinitdata = {
254 { ZORRO_PROD_CBM_A590_A2091_1 },
255 { ZORRO_PROD_CBM_A590_A2091_2 },
256 { 0 }
257};
258MODULE_DEVICE_TABLE(zorro, a2091_zorro_tbl);
259
260static struct zorro_driver a2091_driver = {
261 .name = "a2091",
262 .id_table = a2091_zorro_tbl,
263 .probe = a2091_probe,
264 .remove = __devexit_p(a2091_remove),
265};
266
267static int __init a2091_init(void)
268{
269 return zorro_register_driver(&a2091_driver);
270}
271module_init(a2091_init);
272
273static void __exit a2091_exit(void)
274{
275 zorro_unregister_driver(&a2091_driver);
253} 276}
277module_exit(a2091_exit);
254 278
279MODULE_DESCRIPTION("Commodore A2091/A590 SCSI");
255MODULE_LICENSE("GPL"); 280MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h
index 1c3daa1fd754..794b8e65c711 100644
--- a/drivers/scsi/a2091.h
+++ b/drivers/scsi/a2091.h
@@ -25,7 +25,7 @@
25 */ 25 */
26#define A2091_XFER_MASK (0xff000001) 26#define A2091_XFER_MASK (0xff000001)
27 27
28typedef struct { 28struct a2091_scsiregs {
29 unsigned char pad1[64]; 29 unsigned char pad1[64];
30 volatile unsigned short ISTR; 30 volatile unsigned short ISTR;
31 volatile unsigned short CNTR; 31 volatile unsigned short CNTR;
@@ -44,7 +44,7 @@ typedef struct {
44 volatile unsigned short CINT; 44 volatile unsigned short CINT;
45 unsigned char pad7[2]; 45 unsigned char pad7[2];
46 volatile unsigned short FLUSH; 46 volatile unsigned short FLUSH;
47} a2091_scsiregs; 47};
48 48
49#define DAWR_A2091 (3) 49#define DAWR_A2091 (3)
50 50
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index bc6eb69f5fd0..d9468027fb61 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -1,53 +1,52 @@
1#include <linux/types.h> 1#include <linux/types.h>
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/slab.h>
4#include <linux/blkdev.h>
5#include <linux/ioport.h> 3#include <linux/ioport.h>
6#include <linux/init.h> 4#include <linux/init.h>
5#include <linux/slab.h>
7#include <linux/spinlock.h> 6#include <linux/spinlock.h>
8#include <linux/interrupt.h> 7#include <linux/interrupt.h>
8#include <linux/platform_device.h>
9 9
10#include <asm/setup.h>
11#include <asm/page.h> 10#include <asm/page.h>
12#include <asm/pgtable.h> 11#include <asm/pgtable.h>
13#include <asm/amigaints.h> 12#include <asm/amigaints.h>
14#include <asm/amigahw.h> 13#include <asm/amigahw.h>
15#include <asm/irq.h>
16 14
17#include "scsi.h" 15#include "scsi.h"
18#include <scsi/scsi_host.h>
19#include "wd33c93.h" 16#include "wd33c93.h"
20#include "a3000.h" 17#include "a3000.h"
21 18
22#include <linux/stat.h>
23
24 19
25#define DMA(ptr) ((a3000_scsiregs *)((ptr)->base)) 20struct a3000_hostdata {
26 21 struct WD33C93_hostdata wh;
27static struct Scsi_Host *a3000_host = NULL; 22 struct a3000_scsiregs *regs;
28 23};
29static int a3000_release(struct Scsi_Host *instance);
30 24
31static irqreturn_t a3000_intr(int irq, void *dummy) 25static irqreturn_t a3000_intr(int irq, void *data)
32{ 26{
27 struct Scsi_Host *instance = data;
28 struct a3000_hostdata *hdata = shost_priv(instance);
29 unsigned int status = hdata->regs->ISTR;
33 unsigned long flags; 30 unsigned long flags;
34 unsigned int status = DMA(a3000_host)->ISTR;
35 31
36 if (!(status & ISTR_INT_P)) 32 if (!(status & ISTR_INT_P))
37 return IRQ_NONE; 33 return IRQ_NONE;
38 if (status & ISTR_INTS) { 34 if (status & ISTR_INTS) {
39 spin_lock_irqsave(a3000_host->host_lock, flags); 35 spin_lock_irqsave(instance->host_lock, flags);
40 wd33c93_intr(a3000_host); 36 wd33c93_intr(instance);
41 spin_unlock_irqrestore(a3000_host->host_lock, flags); 37 spin_unlock_irqrestore(instance->host_lock, flags);
42 return IRQ_HANDLED; 38 return IRQ_HANDLED;
43 } 39 }
44 printk("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status); 40 pr_warning("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status);
45 return IRQ_NONE; 41 return IRQ_NONE;
46} 42}
47 43
48static int dma_setup(struct scsi_cmnd *cmd, int dir_in) 44static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
49{ 45{
50 struct WD33C93_hostdata *hdata = shost_priv(a3000_host); 46 struct Scsi_Host *instance = cmd->device->host;
47 struct a3000_hostdata *hdata = shost_priv(instance);
48 struct WD33C93_hostdata *wh = &hdata->wh;
49 struct a3000_scsiregs *regs = hdata->regs;
51 unsigned short cntr = CNTR_PDMD | CNTR_INTEN; 50 unsigned short cntr = CNTR_PDMD | CNTR_INTEN;
52 unsigned long addr = virt_to_bus(cmd->SCp.ptr); 51 unsigned long addr = virt_to_bus(cmd->SCp.ptr);
53 52
@@ -58,23 +57,23 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
58 * buffer 57 * buffer
59 */ 58 */
60 if (addr & A3000_XFER_MASK) { 59 if (addr & A3000_XFER_MASK) {
61 hdata->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; 60 wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff;
62 hdata->dma_bounce_buffer = kmalloc(hdata->dma_bounce_len, 61 wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len,
63 GFP_KERNEL); 62 GFP_KERNEL);
64 63
65 /* can't allocate memory; use PIO */ 64 /* can't allocate memory; use PIO */
66 if (!hdata->dma_bounce_buffer) { 65 if (!wh->dma_bounce_buffer) {
67 hdata->dma_bounce_len = 0; 66 wh->dma_bounce_len = 0;
68 return 1; 67 return 1;
69 } 68 }
70 69
71 if (!dir_in) { 70 if (!dir_in) {
72 /* copy to bounce buffer for a write */ 71 /* copy to bounce buffer for a write */
73 memcpy(hdata->dma_bounce_buffer, cmd->SCp.ptr, 72 memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr,
74 cmd->SCp.this_residual); 73 cmd->SCp.this_residual);
75 } 74 }
76 75
77 addr = virt_to_bus(hdata->dma_bounce_buffer); 76 addr = virt_to_bus(wh->dma_bounce_buffer);
78 } 77 }
79 78
80 /* setup dma direction */ 79 /* setup dma direction */
@@ -82,12 +81,12 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
82 cntr |= CNTR_DDIR; 81 cntr |= CNTR_DDIR;
83 82
84 /* remember direction */ 83 /* remember direction */
85 hdata->dma_dir = dir_in; 84 wh->dma_dir = dir_in;
86 85
87 DMA(a3000_host)->CNTR = cntr; 86 regs->CNTR = cntr;
88 87
89 /* setup DMA *physical* address */ 88 /* setup DMA *physical* address */
90 DMA(a3000_host)->ACR = addr; 89 regs->ACR = addr;
91 90
92 if (dir_in) { 91 if (dir_in) {
93 /* invalidate any cache */ 92 /* invalidate any cache */
@@ -99,7 +98,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
99 98
100 /* start DMA */ 99 /* start DMA */
101 mb(); /* make sure setup is completed */ 100 mb(); /* make sure setup is completed */
102 DMA(a3000_host)->ST_DMA = 1; 101 regs->ST_DMA = 1;
103 mb(); /* make sure DMA has started before next IO */ 102 mb(); /* make sure DMA has started before next IO */
104 103
105 /* return success */ 104 /* return success */
@@ -109,22 +108,24 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
109static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, 108static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
110 int status) 109 int status)
111{ 110{
112 struct WD33C93_hostdata *hdata = shost_priv(instance); 111 struct a3000_hostdata *hdata = shost_priv(instance);
112 struct WD33C93_hostdata *wh = &hdata->wh;
113 struct a3000_scsiregs *regs = hdata->regs;
113 114
114 /* disable SCSI interrupts */ 115 /* disable SCSI interrupts */
115 unsigned short cntr = CNTR_PDMD; 116 unsigned short cntr = CNTR_PDMD;
116 117
117 if (!hdata->dma_dir) 118 if (!wh->dma_dir)
118 cntr |= CNTR_DDIR; 119 cntr |= CNTR_DDIR;
119 120
120 DMA(instance)->CNTR = cntr; 121 regs->CNTR = cntr;
121 mb(); /* make sure CNTR is updated before next IO */ 122 mb(); /* make sure CNTR is updated before next IO */
122 123
123 /* flush if we were reading */ 124 /* flush if we were reading */
124 if (hdata->dma_dir) { 125 if (wh->dma_dir) {
125 DMA(instance)->FLUSH = 1; 126 regs->FLUSH = 1;
126 mb(); /* don't allow prefetch */ 127 mb(); /* don't allow prefetch */
127 while (!(DMA(instance)->ISTR & ISTR_FE_FLG)) 128 while (!(regs->ISTR & ISTR_FE_FLG))
128 barrier(); 129 barrier();
129 mb(); /* no IO until FLUSH is done */ 130 mb(); /* no IO until FLUSH is done */
130 } 131 }
@@ -133,96 +134,54 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
133 /* I think that this CINT is only necessary if you are 134 /* I think that this CINT is only necessary if you are
134 * using the terminal count features. HM 7 Mar 1994 135 * using the terminal count features. HM 7 Mar 1994
135 */ 136 */
136 DMA(instance)->CINT = 1; 137 regs->CINT = 1;
137 138
138 /* stop DMA */ 139 /* stop DMA */
139 DMA(instance)->SP_DMA = 1; 140 regs->SP_DMA = 1;
140 mb(); /* make sure DMA is stopped before next IO */ 141 mb(); /* make sure DMA is stopped before next IO */
141 142
142 /* restore the CONTROL bits (minus the direction flag) */ 143 /* restore the CONTROL bits (minus the direction flag) */
143 DMA(instance)->CNTR = CNTR_PDMD | CNTR_INTEN; 144 regs->CNTR = CNTR_PDMD | CNTR_INTEN;
144 mb(); /* make sure CNTR is updated before next IO */ 145 mb(); /* make sure CNTR is updated before next IO */
145 146
146 /* copy from a bounce buffer, if necessary */ 147 /* copy from a bounce buffer, if necessary */
147 if (status && hdata->dma_bounce_buffer) { 148 if (status && wh->dma_bounce_buffer) {
148 if (SCpnt) { 149 if (SCpnt) {
149 if (hdata->dma_dir && SCpnt) 150 if (wh->dma_dir && SCpnt)
150 memcpy(SCpnt->SCp.ptr, 151 memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer,
151 hdata->dma_bounce_buffer,
152 SCpnt->SCp.this_residual); 152 SCpnt->SCp.this_residual);
153 kfree(hdata->dma_bounce_buffer); 153 kfree(wh->dma_bounce_buffer);
154 hdata->dma_bounce_buffer = NULL; 154 wh->dma_bounce_buffer = NULL;
155 hdata->dma_bounce_len = 0; 155 wh->dma_bounce_len = 0;
156 } else { 156 } else {
157 kfree(hdata->dma_bounce_buffer); 157 kfree(wh->dma_bounce_buffer);
158 hdata->dma_bounce_buffer = NULL; 158 wh->dma_bounce_buffer = NULL;
159 hdata->dma_bounce_len = 0; 159 wh->dma_bounce_len = 0;
160 } 160 }
161 } 161 }
162} 162}
163 163
164static int __init a3000_detect(struct scsi_host_template *tpnt)
165{
166 wd33c93_regs regs;
167 struct WD33C93_hostdata *hdata;
168
169 if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI))
170 return 0;
171 if (!request_mem_region(0xDD0000, 256, "wd33c93"))
172 return 0;
173
174 tpnt->proc_name = "A3000";
175 tpnt->proc_info = &wd33c93_proc_info;
176
177 a3000_host = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
178 if (a3000_host == NULL)
179 goto fail_register;
180
181 a3000_host->base = ZTWO_VADDR(0xDD0000);
182 a3000_host->irq = IRQ_AMIGA_PORTS;
183 DMA(a3000_host)->DAWR = DAWR_A3000;
184 regs.SASR = &(DMA(a3000_host)->SASR);
185 regs.SCMD = &(DMA(a3000_host)->SCMD);
186 hdata = shost_priv(a3000_host);
187 hdata->no_sync = 0xff;
188 hdata->fast = 0;
189 hdata->dma_mode = CTRL_DMA;
190 wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15);
191 if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI",
192 a3000_intr))
193 goto fail_irq;
194 DMA(a3000_host)->CNTR = CNTR_PDMD | CNTR_INTEN;
195
196 return 1;
197
198fail_irq:
199 scsi_unregister(a3000_host);
200fail_register:
201 release_mem_region(0xDD0000, 256);
202 return 0;
203}
204
205static int a3000_bus_reset(struct scsi_cmnd *cmd) 164static int a3000_bus_reset(struct scsi_cmnd *cmd)
206{ 165{
166 struct Scsi_Host *instance = cmd->device->host;
167
207 /* FIXME perform bus-specific reset */ 168 /* FIXME perform bus-specific reset */
208 169
209 /* FIXME 2: kill this entire function, which should 170 /* FIXME 2: kill this entire function, which should
210 cause mid-layer to call wd33c93_host_reset anyway? */ 171 cause mid-layer to call wd33c93_host_reset anyway? */
211 172
212 spin_lock_irq(cmd->device->host->host_lock); 173 spin_lock_irq(instance->host_lock);
213 wd33c93_host_reset(cmd); 174 wd33c93_host_reset(cmd);
214 spin_unlock_irq(cmd->device->host->host_lock); 175 spin_unlock_irq(instance->host_lock);
215 176
216 return SUCCESS; 177 return SUCCESS;
217} 178}
218 179
219#define HOSTS_C 180static struct scsi_host_template amiga_a3000_scsi_template = {
220 181 .module = THIS_MODULE,
221static struct scsi_host_template driver_template = {
222 .proc_name = "A3000",
223 .name = "Amiga 3000 built-in SCSI", 182 .name = "Amiga 3000 built-in SCSI",
224 .detect = a3000_detect, 183 .proc_info = wd33c93_proc_info,
225 .release = a3000_release, 184 .proc_name = "A3000",
226 .queuecommand = wd33c93_queuecommand, 185 .queuecommand = wd33c93_queuecommand,
227 .eh_abort_handler = wd33c93_abort, 186 .eh_abort_handler = wd33c93_abort,
228 .eh_bus_reset_handler = a3000_bus_reset, 187 .eh_bus_reset_handler = a3000_bus_reset,
@@ -234,15 +193,104 @@ static struct scsi_host_template driver_template = {
234 .use_clustering = ENABLE_CLUSTERING 193 .use_clustering = ENABLE_CLUSTERING
235}; 194};
236 195
196static int __init amiga_a3000_scsi_probe(struct platform_device *pdev)
197{
198 struct resource *res;
199 struct Scsi_Host *instance;
200 int error;
201 struct a3000_scsiregs *regs;
202 wd33c93_regs wdregs;
203 struct a3000_hostdata *hdata;
204
205 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
206 if (!res)
207 return -ENODEV;
208
209 if (!request_mem_region(res->start, resource_size(res), "wd33c93"))
210 return -EBUSY;
211
212 instance = scsi_host_alloc(&amiga_a3000_scsi_template,
213 sizeof(struct a3000_hostdata));
214 if (!instance) {
215 error = -ENOMEM;
216 goto fail_alloc;
217 }
218
219 instance->irq = IRQ_AMIGA_PORTS;
237 220
238#include "scsi_module.c" 221 regs = (struct a3000_scsiregs *)ZTWO_VADDR(res->start);
222 regs->DAWR = DAWR_A3000;
223
224 wdregs.SASR = &regs->SASR;
225 wdregs.SCMD = &regs->SCMD;
226
227 hdata = shost_priv(instance);
228 hdata->wh.no_sync = 0xff;
229 hdata->wh.fast = 0;
230 hdata->wh.dma_mode = CTRL_DMA;
231 hdata->regs = regs;
232
233 wd33c93_init(instance, wdregs, dma_setup, dma_stop, WD33C93_FS_12_15);
234 error = request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED,
235 "A3000 SCSI", instance);
236 if (error)
237 goto fail_irq;
238
239 regs->CNTR = CNTR_PDMD | CNTR_INTEN;
240
241 error = scsi_add_host(instance, NULL);
242 if (error)
243 goto fail_host;
244
245 platform_set_drvdata(pdev, instance);
246
247 scsi_scan_host(instance);
248 return 0;
249
250fail_host:
251 free_irq(IRQ_AMIGA_PORTS, instance);
252fail_irq:
253 scsi_host_put(instance);
254fail_alloc:
255 release_mem_region(res->start, resource_size(res));
256 return error;
257}
258
259static int __exit amiga_a3000_scsi_remove(struct platform_device *pdev)
260{
261 struct Scsi_Host *instance = platform_get_drvdata(pdev);
262 struct a3000_hostdata *hdata = shost_priv(instance);
263 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
264
265 hdata->regs->CNTR = 0;
266 scsi_remove_host(instance);
267 free_irq(IRQ_AMIGA_PORTS, instance);
268 scsi_host_put(instance);
269 release_mem_region(res->start, resource_size(res));
270 return 0;
271}
272
273static struct platform_driver amiga_a3000_scsi_driver = {
274 .remove = __exit_p(amiga_a3000_scsi_remove),
275 .driver = {
276 .name = "amiga-a3000-scsi",
277 .owner = THIS_MODULE,
278 },
279};
280
281static int __init amiga_a3000_scsi_init(void)
282{
283 return platform_driver_probe(&amiga_a3000_scsi_driver,
284 amiga_a3000_scsi_probe);
285}
286module_init(amiga_a3000_scsi_init);
239 287
240static int a3000_release(struct Scsi_Host *instance) 288static void __exit amiga_a3000_scsi_exit(void)
241{ 289{
242 DMA(instance)->CNTR = 0; 290 platform_driver_unregister(&amiga_a3000_scsi_driver);
243 release_mem_region(0xDD0000, 256);
244 free_irq(IRQ_AMIGA_PORTS, a3000_intr);
245 return 1;
246} 291}
292module_exit(amiga_a3000_scsi_exit);
247 293
294MODULE_DESCRIPTION("Amiga 3000 built-in SCSI");
248MODULE_LICENSE("GPL"); 295MODULE_LICENSE("GPL");
296MODULE_ALIAS("platform:amiga-a3000-scsi");
diff --git a/drivers/scsi/a3000.h b/drivers/scsi/a3000.h
index 684813ee378c..49db4a335aab 100644
--- a/drivers/scsi/a3000.h
+++ b/drivers/scsi/a3000.h
@@ -25,7 +25,7 @@
25 */ 25 */
26#define A3000_XFER_MASK (0x00000003) 26#define A3000_XFER_MASK (0x00000003)
27 27
28typedef struct { 28struct a3000_scsiregs {
29 unsigned char pad1[2]; 29 unsigned char pad1[2];
30 volatile unsigned short DAWR; 30 volatile unsigned short DAWR;
31 volatile unsigned int WTC; 31 volatile unsigned int WTC;
@@ -46,7 +46,7 @@ typedef struct {
46 volatile unsigned char SASR; 46 volatile unsigned char SASR;
47 unsigned char pad9; 47 unsigned char pad9;
48 volatile unsigned char SCMD; 48 volatile unsigned char SCMD;
49} a3000_scsiregs; 49};
50 50
51#define DAWR_A3000 (3) 51#define DAWR_A3000 (3)
52 52
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c
index 11ae6be8aeaf..23c76f41883c 100644
--- a/drivers/scsi/a4000t.c
+++ b/drivers/scsi/a4000t.c
@@ -20,10 +20,6 @@
20 20
21#include "53c700.h" 21#include "53c700.h"
22 22
23MODULE_AUTHOR("Alan Hourihane <alanh@fairlite.demon.co.uk> / Kars de Jong <jongk@linux-m68k.org>");
24MODULE_DESCRIPTION("Amiga A4000T NCR53C710 driver");
25MODULE_LICENSE("GPL");
26
27 23
28static struct scsi_host_template a4000t_scsi_driver_template = { 24static struct scsi_host_template a4000t_scsi_driver_template = {
29 .name = "A4000T builtin SCSI", 25 .name = "A4000T builtin SCSI",
@@ -32,30 +28,35 @@ static struct scsi_host_template a4000t_scsi_driver_template = {
32 .module = THIS_MODULE, 28 .module = THIS_MODULE,
33}; 29};
34 30
35static struct platform_device *a4000t_scsi_device;
36 31
37#define A4000T_SCSI_ADDR 0xdd0040 32#define A4000T_SCSI_OFFSET 0x40
38 33
39static int __devinit a4000t_probe(struct platform_device *dev) 34static int __init amiga_a4000t_scsi_probe(struct platform_device *pdev)
40{ 35{
41 struct Scsi_Host *host; 36 struct resource *res;
37 phys_addr_t scsi_addr;
42 struct NCR_700_Host_Parameters *hostdata; 38 struct NCR_700_Host_Parameters *hostdata;
39 struct Scsi_Host *host;
43 40
44 if (!(MACH_IS_AMIGA && AMIGAHW_PRESENT(A4000_SCSI))) 41 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
45 goto out; 42 if (!res)
43 return -ENODEV;
46 44
47 if (!request_mem_region(A4000T_SCSI_ADDR, 0x1000, 45 if (!request_mem_region(res->start, resource_size(res),
48 "A4000T builtin SCSI")) 46 "A4000T builtin SCSI"))
49 goto out; 47 return -EBUSY;
50 48
51 hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); 49 hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters),
50 GFP_KERNEL);
52 if (!hostdata) { 51 if (!hostdata) {
53 printk(KERN_ERR "a4000t-scsi: Failed to allocate host data\n"); 52 dev_err(&pdev->dev, "Failed to allocate host data\n");
54 goto out_release; 53 goto out_release;
55 } 54 }
56 55
56 scsi_addr = res->start + A4000T_SCSI_OFFSET;
57
57 /* Fill in the required pieces of hostdata */ 58 /* Fill in the required pieces of hostdata */
58 hostdata->base = (void __iomem *)ZTWO_VADDR(A4000T_SCSI_ADDR); 59 hostdata->base = (void __iomem *)ZTWO_VADDR(scsi_addr);
59 hostdata->clock = 50; 60 hostdata->clock = 50;
60 hostdata->chip710 = 1; 61 hostdata->chip710 = 1;
61 hostdata->dmode_extra = DMODE_FC2; 62 hostdata->dmode_extra = DMODE_FC2;
@@ -63,26 +64,25 @@ static int __devinit a4000t_probe(struct platform_device *dev)
63 64
64 /* and register the chip */ 65 /* and register the chip */
65 host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata, 66 host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata,
66 &dev->dev); 67 &pdev->dev);
67 if (!host) { 68 if (!host) {
68 printk(KERN_ERR "a4000t-scsi: No host detected; " 69 dev_err(&pdev->dev,
69 "board configuration problem?\n"); 70 "No host detected; board configuration problem?\n");
70 goto out_free; 71 goto out_free;
71 } 72 }
72 73
73 host->this_id = 7; 74 host->this_id = 7;
74 host->base = A4000T_SCSI_ADDR; 75 host->base = scsi_addr;
75 host->irq = IRQ_AMIGA_PORTS; 76 host->irq = IRQ_AMIGA_PORTS;
76 77
77 if (request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "a4000t-scsi", 78 if (request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "a4000t-scsi",
78 host)) { 79 host)) {
79 printk(KERN_ERR "a4000t-scsi: request_irq failed\n"); 80 dev_err(&pdev->dev, "request_irq failed\n");
80 goto out_put_host; 81 goto out_put_host;
81 } 82 }
82 83
83 platform_set_drvdata(dev, host); 84 platform_set_drvdata(pdev, host);
84 scsi_scan_host(host); 85 scsi_scan_host(host);
85
86 return 0; 86 return 0;
87 87
88 out_put_host: 88 out_put_host:
@@ -90,58 +90,49 @@ static int __devinit a4000t_probe(struct platform_device *dev)
90 out_free: 90 out_free:
91 kfree(hostdata); 91 kfree(hostdata);
92 out_release: 92 out_release:
93 release_mem_region(A4000T_SCSI_ADDR, 0x1000); 93 release_mem_region(res->start, resource_size(res));
94 out:
95 return -ENODEV; 94 return -ENODEV;
96} 95}
97 96
98static __devexit int a4000t_device_remove(struct platform_device *dev) 97static int __exit amiga_a4000t_scsi_remove(struct platform_device *pdev)
99{ 98{
100 struct Scsi_Host *host = platform_get_drvdata(dev); 99 struct Scsi_Host *host = platform_get_drvdata(pdev);
101 struct NCR_700_Host_Parameters *hostdata = shost_priv(host); 100 struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
101 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
102 102
103 scsi_remove_host(host); 103 scsi_remove_host(host);
104
105 NCR_700_release(host); 104 NCR_700_release(host);
106 kfree(hostdata); 105 kfree(hostdata);
107 free_irq(host->irq, host); 106 free_irq(host->irq, host);
108 release_mem_region(A4000T_SCSI_ADDR, 0x1000); 107 release_mem_region(res->start, resource_size(res));
109
110 return 0; 108 return 0;
111} 109}
112 110
113static struct platform_driver a4000t_scsi_driver = { 111static struct platform_driver amiga_a4000t_scsi_driver = {
114 .driver = { 112 .remove = __exit_p(amiga_a4000t_scsi_remove),
115 .name = "a4000t-scsi", 113 .driver = {
116 .owner = THIS_MODULE, 114 .name = "amiga-a4000t-scsi",
115 .owner = THIS_MODULE,
117 }, 116 },
118 .probe = a4000t_probe,
119 .remove = __devexit_p(a4000t_device_remove),
120}; 117};
121 118
122static int __init a4000t_scsi_init(void) 119static int __init amiga_a4000t_scsi_init(void)
123{ 120{
124 int err; 121 return platform_driver_probe(&amiga_a4000t_scsi_driver,
125 122 amiga_a4000t_scsi_probe);
126 err = platform_driver_register(&a4000t_scsi_driver);
127 if (err)
128 return err;
129
130 a4000t_scsi_device = platform_device_register_simple("a4000t-scsi",
131 -1, NULL, 0);
132 if (IS_ERR(a4000t_scsi_device)) {
133 platform_driver_unregister(&a4000t_scsi_driver);
134 return PTR_ERR(a4000t_scsi_device);
135 }
136
137 return err;
138} 123}
139 124
140static void __exit a4000t_scsi_exit(void) 125module_init(amiga_a4000t_scsi_init);
126
127static void __exit amiga_a4000t_scsi_exit(void)
141{ 128{
142 platform_device_unregister(a4000t_scsi_device); 129 platform_driver_unregister(&amiga_a4000t_scsi_driver);
143 platform_driver_unregister(&a4000t_scsi_driver);
144} 130}
145 131
146module_init(a4000t_scsi_init); 132module_exit(amiga_a4000t_scsi_exit);
147module_exit(a4000t_scsi_exit); 133
134MODULE_AUTHOR("Alan Hourihane <alanh@fairlite.demon.co.uk> / "
135 "Kars de Jong <jongk@linux-m68k.org>");
136MODULE_DESCRIPTION("Amiga A4000T NCR53C710 driver");
137MODULE_LICENSE("GPL");
138MODULE_ALIAS("platform:amiga-a4000t-scsi");
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index 18b7102bb80e..2ce26eb7a1ec 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -1,36 +1,35 @@
1#include <linux/types.h> 1#include <linux/types.h>
2#include <linux/mm.h>
3#include <linux/slab.h>
4#include <linux/blkdev.h>
5#include <linux/init.h> 2#include <linux/init.h>
6#include <linux/interrupt.h> 3#include <linux/interrupt.h>
4#include <linux/mm.h>
5#include <linux/slab.h>
6#include <linux/spinlock.h>
7#include <linux/zorro.h>
7 8
8#include <asm/setup.h>
9#include <asm/page.h> 9#include <asm/page.h>
10#include <asm/pgtable.h> 10#include <asm/pgtable.h>
11#include <asm/amigaints.h> 11#include <asm/amigaints.h>
12#include <asm/amigahw.h> 12#include <asm/amigahw.h>
13#include <linux/zorro.h>
14#include <asm/irq.h>
15#include <linux/spinlock.h>
16 13
17#include "scsi.h" 14#include "scsi.h"
18#include <scsi/scsi_host.h>
19#include "wd33c93.h" 15#include "wd33c93.h"
20#include "gvp11.h" 16#include "gvp11.h"
21 17
22#include <linux/stat.h>
23 18
19#define CHECK_WD33C93
24 20
25#define DMA(ptr) ((gvp11_scsiregs *)((ptr)->base)) 21struct gvp11_hostdata {
22 struct WD33C93_hostdata wh;
23 struct gvp11_scsiregs *regs;
24};
26 25
27static irqreturn_t gvp11_intr(int irq, void *_instance) 26static irqreturn_t gvp11_intr(int irq, void *data)
28{ 27{
28 struct Scsi_Host *instance = data;
29 struct gvp11_hostdata *hdata = shost_priv(instance);
30 unsigned int status = hdata->regs->CNTR;
29 unsigned long flags; 31 unsigned long flags;
30 unsigned int status;
31 struct Scsi_Host *instance = (struct Scsi_Host *)_instance;
32 32
33 status = DMA(instance)->CNTR;
34 if (!(status & GVP11_DMAC_INT_PENDING)) 33 if (!(status & GVP11_DMAC_INT_PENDING))
35 return IRQ_NONE; 34 return IRQ_NONE;
36 35
@@ -50,64 +49,66 @@ void gvp11_setup(char *str, int *ints)
50static int dma_setup(struct scsi_cmnd *cmd, int dir_in) 49static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
51{ 50{
52 struct Scsi_Host *instance = cmd->device->host; 51 struct Scsi_Host *instance = cmd->device->host;
53 struct WD33C93_hostdata *hdata = shost_priv(instance); 52 struct gvp11_hostdata *hdata = shost_priv(instance);
53 struct WD33C93_hostdata *wh = &hdata->wh;
54 struct gvp11_scsiregs *regs = hdata->regs;
54 unsigned short cntr = GVP11_DMAC_INT_ENABLE; 55 unsigned short cntr = GVP11_DMAC_INT_ENABLE;
55 unsigned long addr = virt_to_bus(cmd->SCp.ptr); 56 unsigned long addr = virt_to_bus(cmd->SCp.ptr);
56 int bank_mask; 57 int bank_mask;
57 static int scsi_alloc_out_of_range = 0; 58 static int scsi_alloc_out_of_range = 0;
58 59
59 /* use bounce buffer if the physical address is bad */ 60 /* use bounce buffer if the physical address is bad */
60 if (addr & hdata->dma_xfer_mask) { 61 if (addr & wh->dma_xfer_mask) {
61 hdata->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; 62 wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff;
62 63
63 if (!scsi_alloc_out_of_range) { 64 if (!scsi_alloc_out_of_range) {
64 hdata->dma_bounce_buffer = 65 wh->dma_bounce_buffer =
65 kmalloc(hdata->dma_bounce_len, GFP_KERNEL); 66 kmalloc(wh->dma_bounce_len, GFP_KERNEL);
66 hdata->dma_buffer_pool = BUF_SCSI_ALLOCED; 67 wh->dma_buffer_pool = BUF_SCSI_ALLOCED;
67 } 68 }
68 69
69 if (scsi_alloc_out_of_range || 70 if (scsi_alloc_out_of_range ||
70 !hdata->dma_bounce_buffer) { 71 !wh->dma_bounce_buffer) {
71 hdata->dma_bounce_buffer = 72 wh->dma_bounce_buffer =
72 amiga_chip_alloc(hdata->dma_bounce_len, 73 amiga_chip_alloc(wh->dma_bounce_len,
73 "GVP II SCSI Bounce Buffer"); 74 "GVP II SCSI Bounce Buffer");
74 75
75 if (!hdata->dma_bounce_buffer) { 76 if (!wh->dma_bounce_buffer) {
76 hdata->dma_bounce_len = 0; 77 wh->dma_bounce_len = 0;
77 return 1; 78 return 1;
78 } 79 }
79 80
80 hdata->dma_buffer_pool = BUF_CHIP_ALLOCED; 81 wh->dma_buffer_pool = BUF_CHIP_ALLOCED;
81 } 82 }
82 83
83 /* check if the address of the bounce buffer is OK */ 84 /* check if the address of the bounce buffer is OK */
84 addr = virt_to_bus(hdata->dma_bounce_buffer); 85 addr = virt_to_bus(wh->dma_bounce_buffer);
85 86
86 if (addr & hdata->dma_xfer_mask) { 87 if (addr & wh->dma_xfer_mask) {
87 /* fall back to Chip RAM if address out of range */ 88 /* fall back to Chip RAM if address out of range */
88 if (hdata->dma_buffer_pool == BUF_SCSI_ALLOCED) { 89 if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED) {
89 kfree(hdata->dma_bounce_buffer); 90 kfree(wh->dma_bounce_buffer);
90 scsi_alloc_out_of_range = 1; 91 scsi_alloc_out_of_range = 1;
91 } else { 92 } else {
92 amiga_chip_free(hdata->dma_bounce_buffer); 93 amiga_chip_free(wh->dma_bounce_buffer);
93 } 94 }
94 95
95 hdata->dma_bounce_buffer = 96 wh->dma_bounce_buffer =
96 amiga_chip_alloc(hdata->dma_bounce_len, 97 amiga_chip_alloc(wh->dma_bounce_len,
97 "GVP II SCSI Bounce Buffer"); 98 "GVP II SCSI Bounce Buffer");
98 99
99 if (!hdata->dma_bounce_buffer) { 100 if (!wh->dma_bounce_buffer) {
100 hdata->dma_bounce_len = 0; 101 wh->dma_bounce_len = 0;
101 return 1; 102 return 1;
102 } 103 }
103 104
104 addr = virt_to_bus(hdata->dma_bounce_buffer); 105 addr = virt_to_bus(wh->dma_bounce_buffer);
105 hdata->dma_buffer_pool = BUF_CHIP_ALLOCED; 106 wh->dma_buffer_pool = BUF_CHIP_ALLOCED;
106 } 107 }
107 108
108 if (!dir_in) { 109 if (!dir_in) {
109 /* copy to bounce buffer for a write */ 110 /* copy to bounce buffer for a write */
110 memcpy(hdata->dma_bounce_buffer, cmd->SCp.ptr, 111 memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr,
111 cmd->SCp.this_residual); 112 cmd->SCp.this_residual);
112 } 113 }
113 } 114 }
@@ -116,11 +117,11 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
116 if (!dir_in) 117 if (!dir_in)
117 cntr |= GVP11_DMAC_DIR_WRITE; 118 cntr |= GVP11_DMAC_DIR_WRITE;
118 119
119 hdata->dma_dir = dir_in; 120 wh->dma_dir = dir_in;
120 DMA(cmd->device->host)->CNTR = cntr; 121 regs->CNTR = cntr;
121 122
122 /* setup DMA *physical* address */ 123 /* setup DMA *physical* address */
123 DMA(cmd->device->host)->ACR = addr; 124 regs->ACR = addr;
124 125
125 if (dir_in) { 126 if (dir_in) {
126 /* invalidate any cache */ 127 /* invalidate any cache */
@@ -130,12 +131,12 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
130 cache_push(addr, cmd->SCp.this_residual); 131 cache_push(addr, cmd->SCp.this_residual);
131 } 132 }
132 133
133 bank_mask = (~hdata->dma_xfer_mask >> 18) & 0x01c0; 134 bank_mask = (~wh->dma_xfer_mask >> 18) & 0x01c0;
134 if (bank_mask) 135 if (bank_mask)
135 DMA(cmd->device->host)->BANK = bank_mask & (addr >> 18); 136 regs->BANK = bank_mask & (addr >> 18);
136 137
137 /* start DMA */ 138 /* start DMA */
138 DMA(cmd->device->host)->ST_DMA = 1; 139 regs->ST_DMA = 1;
139 140
140 /* return success */ 141 /* return success */
141 return 0; 142 return 0;
@@ -144,236 +145,53 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
144static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, 145static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
145 int status) 146 int status)
146{ 147{
147 struct WD33C93_hostdata *hdata = shost_priv(instance); 148 struct gvp11_hostdata *hdata = shost_priv(instance);
149 struct WD33C93_hostdata *wh = &hdata->wh;
150 struct gvp11_scsiregs *regs = hdata->regs;
148 151
149 /* stop DMA */ 152 /* stop DMA */
150 DMA(instance)->SP_DMA = 1; 153 regs->SP_DMA = 1;
151 /* remove write bit from CONTROL bits */ 154 /* remove write bit from CONTROL bits */
152 DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE; 155 regs->CNTR = GVP11_DMAC_INT_ENABLE;
153 156
154 /* copy from a bounce buffer, if necessary */ 157 /* copy from a bounce buffer, if necessary */
155 if (status && hdata->dma_bounce_buffer) { 158 if (status && wh->dma_bounce_buffer) {
156 if (hdata->dma_dir && SCpnt) 159 if (wh->dma_dir && SCpnt)
157 memcpy(SCpnt->SCp.ptr, hdata->dma_bounce_buffer, 160 memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer,
158 SCpnt->SCp.this_residual); 161 SCpnt->SCp.this_residual);
159 162
160 if (hdata->dma_buffer_pool == BUF_SCSI_ALLOCED) 163 if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED)
161 kfree(hdata->dma_bounce_buffer); 164 kfree(wh->dma_bounce_buffer);
162 else
163 amiga_chip_free(hdata->dma_bounce_buffer);
164
165 hdata->dma_bounce_buffer = NULL;
166 hdata->dma_bounce_len = 0;
167 }
168}
169
170#define CHECK_WD33C93
171
172int __init gvp11_detect(struct scsi_host_template *tpnt)
173{
174 static unsigned char called = 0;
175 struct Scsi_Host *instance;
176 unsigned long address;
177 unsigned int epc;
178 struct zorro_dev *z = NULL;
179 unsigned int default_dma_xfer_mask;
180 struct WD33C93_hostdata *hdata;
181 wd33c93_regs regs;
182 int num_gvp11 = 0;
183#ifdef CHECK_WD33C93
184 volatile unsigned char *sasr_3393, *scmd_3393;
185 unsigned char save_sasr;
186 unsigned char q, qq;
187#endif
188
189 if (!MACH_IS_AMIGA || called)
190 return 0;
191 called = 1;
192
193 tpnt->proc_name = "GVP11";
194 tpnt->proc_info = &wd33c93_proc_info;
195
196 while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
197 /*
198 * This should (hopefully) be the correct way to identify
199 * all the different GVP SCSI controllers (except for the
200 * SERIES I though).
201 */
202
203 if (z->id == ZORRO_PROD_GVP_COMBO_030_R3_SCSI ||
204 z->id == ZORRO_PROD_GVP_SERIES_II)
205 default_dma_xfer_mask = ~0x00ffffff;
206 else if (z->id == ZORRO_PROD_GVP_GFORCE_030_SCSI ||
207 z->id == ZORRO_PROD_GVP_A530_SCSI ||
208 z->id == ZORRO_PROD_GVP_COMBO_030_R4_SCSI)
209 default_dma_xfer_mask = ~0x01ffffff;
210 else if (z->id == ZORRO_PROD_GVP_A1291 ||
211 z->id == ZORRO_PROD_GVP_GFORCE_040_SCSI_1)
212 default_dma_xfer_mask = ~0x07ffffff;
213 else 165 else
214 continue; 166 amiga_chip_free(wh->dma_bounce_buffer);
215
216 /*
217 * Rumors state that some GVP ram boards use the same product
218 * code as the SCSI controllers. Therefore if the board-size
219 * is not 64KB we asume it is a ram board and bail out.
220 */
221 if (z->resource.end - z->resource.start != 0xffff)
222 continue;
223 167
224 address = z->resource.start; 168 wh->dma_bounce_buffer = NULL;
225 if (!request_mem_region(address, 256, "wd33c93")) 169 wh->dma_bounce_len = 0;
226 continue;
227
228#ifdef CHECK_WD33C93
229
230 /*
231 * These darn GVP boards are a problem - it can be tough to tell
232 * whether or not they include a SCSI controller. This is the
233 * ultimate Yet-Another-GVP-Detection-Hack in that it actually
234 * probes for a WD33c93 chip: If we find one, it's extremely
235 * likely that this card supports SCSI, regardless of Product_
236 * Code, Board_Size, etc.
237 */
238
239 /* Get pointers to the presumed register locations and save contents */
240
241 sasr_3393 = &(((gvp11_scsiregs *)(ZTWO_VADDR(address)))->SASR);
242 scmd_3393 = &(((gvp11_scsiregs *)(ZTWO_VADDR(address)))->SCMD);
243 save_sasr = *sasr_3393;
244
245 /* First test the AuxStatus Reg */
246
247 q = *sasr_3393; /* read it */
248 if (q & 0x08) /* bit 3 should always be clear */
249 goto release;
250 *sasr_3393 = WD_AUXILIARY_STATUS; /* setup indirect address */
251 if (*sasr_3393 == WD_AUXILIARY_STATUS) { /* shouldn't retain the write */
252 *sasr_3393 = save_sasr; /* Oops - restore this byte */
253 goto release;
254 }
255 if (*sasr_3393 != q) { /* should still read the same */
256 *sasr_3393 = save_sasr; /* Oops - restore this byte */
257 goto release;
258 }
259 if (*scmd_3393 != q) /* and so should the image at 0x1f */
260 goto release;
261
262 /*
263 * Ok, we probably have a wd33c93, but let's check a few other places
264 * for good measure. Make sure that this works for both 'A and 'B
265 * chip versions.
266 */
267
268 *sasr_3393 = WD_SCSI_STATUS;
269 q = *scmd_3393;
270 *sasr_3393 = WD_SCSI_STATUS;
271 *scmd_3393 = ~q;
272 *sasr_3393 = WD_SCSI_STATUS;
273 qq = *scmd_3393;
274 *sasr_3393 = WD_SCSI_STATUS;
275 *scmd_3393 = q;
276 if (qq != q) /* should be read only */
277 goto release;
278 *sasr_3393 = 0x1e; /* this register is unimplemented */
279 q = *scmd_3393;
280 *sasr_3393 = 0x1e;
281 *scmd_3393 = ~q;
282 *sasr_3393 = 0x1e;
283 qq = *scmd_3393;
284 *sasr_3393 = 0x1e;
285 *scmd_3393 = q;
286 if (qq != q || qq != 0xff) /* should be read only, all 1's */
287 goto release;
288 *sasr_3393 = WD_TIMEOUT_PERIOD;
289 q = *scmd_3393;
290 *sasr_3393 = WD_TIMEOUT_PERIOD;
291 *scmd_3393 = ~q;
292 *sasr_3393 = WD_TIMEOUT_PERIOD;
293 qq = *scmd_3393;
294 *sasr_3393 = WD_TIMEOUT_PERIOD;
295 *scmd_3393 = q;
296 if (qq != (~q & 0xff)) /* should be read/write */
297 goto release;
298#endif
299
300 instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
301 if (instance == NULL)
302 goto release;
303 instance->base = ZTWO_VADDR(address);
304 instance->irq = IRQ_AMIGA_PORTS;
305 instance->unique_id = z->slotaddr;
306
307 hdata = shost_priv(instance);
308 if (gvp11_xfer_mask)
309 hdata->dma_xfer_mask = gvp11_xfer_mask;
310 else
311 hdata->dma_xfer_mask = default_dma_xfer_mask;
312
313 DMA(instance)->secret2 = 1;
314 DMA(instance)->secret1 = 0;
315 DMA(instance)->secret3 = 15;
316 while (DMA(instance)->CNTR & GVP11_DMAC_BUSY)
317 ;
318 DMA(instance)->CNTR = 0;
319
320 DMA(instance)->BANK = 0;
321
322 epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000);
323
324 /*
325 * Check for 14MHz SCSI clock
326 */
327 regs.SASR = &(DMA(instance)->SASR);
328 regs.SCMD = &(DMA(instance)->SCMD);
329 hdata->no_sync = 0xff;
330 hdata->fast = 0;
331 hdata->dma_mode = CTRL_DMA;
332 wd33c93_init(instance, regs, dma_setup, dma_stop,
333 (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10
334 : WD33C93_FS_12_15);
335
336 if (request_irq(IRQ_AMIGA_PORTS, gvp11_intr, IRQF_SHARED,
337 "GVP11 SCSI", instance))
338 goto unregister;
339 DMA(instance)->CNTR = GVP11_DMAC_INT_ENABLE;
340 num_gvp11++;
341 continue;
342
343unregister:
344 scsi_unregister(instance);
345release:
346 release_mem_region(address, 256);
347 } 170 }
348
349 return num_gvp11;
350} 171}
351 172
352static int gvp11_bus_reset(struct scsi_cmnd *cmd) 173static int gvp11_bus_reset(struct scsi_cmnd *cmd)
353{ 174{
175 struct Scsi_Host *instance = cmd->device->host;
176
354 /* FIXME perform bus-specific reset */ 177 /* FIXME perform bus-specific reset */
355 178
356 /* FIXME 2: shouldn't we no-op this function (return 179 /* FIXME 2: shouldn't we no-op this function (return
357 FAILED), and fall back to host reset function, 180 FAILED), and fall back to host reset function,
358 wd33c93_host_reset ? */ 181 wd33c93_host_reset ? */
359 182
360 spin_lock_irq(cmd->device->host->host_lock); 183 spin_lock_irq(instance->host_lock);
361 wd33c93_host_reset(cmd); 184 wd33c93_host_reset(cmd);
362 spin_unlock_irq(cmd->device->host->host_lock); 185 spin_unlock_irq(instance->host_lock);
363 186
364 return SUCCESS; 187 return SUCCESS;
365} 188}
366 189
367 190static struct scsi_host_template gvp11_scsi_template = {
368#define HOSTS_C 191 .module = THIS_MODULE,
369
370#include "gvp11.h"
371
372static struct scsi_host_template driver_template = {
373 .proc_name = "GVP11",
374 .name = "GVP Series II SCSI", 192 .name = "GVP Series II SCSI",
375 .detect = gvp11_detect, 193 .proc_info = wd33c93_proc_info,
376 .release = gvp11_release, 194 .proc_name = "GVP11",
377 .queuecommand = wd33c93_queuecommand, 195 .queuecommand = wd33c93_queuecommand,
378 .eh_abort_handler = wd33c93_abort, 196 .eh_abort_handler = wd33c93_abort,
379 .eh_bus_reset_handler = gvp11_bus_reset, 197 .eh_bus_reset_handler = gvp11_bus_reset,
@@ -385,17 +203,230 @@ static struct scsi_host_template driver_template = {
385 .use_clustering = DISABLE_CLUSTERING 203 .use_clustering = DISABLE_CLUSTERING
386}; 204};
387 205
206static int __devinit check_wd33c93(struct gvp11_scsiregs *regs)
207{
208#ifdef CHECK_WD33C93
209 volatile unsigned char *sasr_3393, *scmd_3393;
210 unsigned char save_sasr;
211 unsigned char q, qq;
388 212
389#include "scsi_module.c" 213 /*
214 * These darn GVP boards are a problem - it can be tough to tell
215 * whether or not they include a SCSI controller. This is the
216 * ultimate Yet-Another-GVP-Detection-Hack in that it actually
217 * probes for a WD33c93 chip: If we find one, it's extremely
218 * likely that this card supports SCSI, regardless of Product_
219 * Code, Board_Size, etc.
220 */
221
222 /* Get pointers to the presumed register locations and save contents */
223
224 sasr_3393 = &regs->SASR;
225 scmd_3393 = &regs->SCMD;
226 save_sasr = *sasr_3393;
227
228 /* First test the AuxStatus Reg */
229
230 q = *sasr_3393; /* read it */
231 if (q & 0x08) /* bit 3 should always be clear */
232 return -ENODEV;
233 *sasr_3393 = WD_AUXILIARY_STATUS; /* setup indirect address */
234 if (*sasr_3393 == WD_AUXILIARY_STATUS) { /* shouldn't retain the write */
235 *sasr_3393 = save_sasr; /* Oops - restore this byte */
236 return -ENODEV;
237 }
238 if (*sasr_3393 != q) { /* should still read the same */
239 *sasr_3393 = save_sasr; /* Oops - restore this byte */
240 return -ENODEV;
241 }
242 if (*scmd_3393 != q) /* and so should the image at 0x1f */
243 return -ENODEV;
244
245 /*
246 * Ok, we probably have a wd33c93, but let's check a few other places
247 * for good measure. Make sure that this works for both 'A and 'B
248 * chip versions.
249 */
250
251 *sasr_3393 = WD_SCSI_STATUS;
252 q = *scmd_3393;
253 *sasr_3393 = WD_SCSI_STATUS;
254 *scmd_3393 = ~q;
255 *sasr_3393 = WD_SCSI_STATUS;
256 qq = *scmd_3393;
257 *sasr_3393 = WD_SCSI_STATUS;
258 *scmd_3393 = q;
259 if (qq != q) /* should be read only */
260 return -ENODEV;
261 *sasr_3393 = 0x1e; /* this register is unimplemented */
262 q = *scmd_3393;
263 *sasr_3393 = 0x1e;
264 *scmd_3393 = ~q;
265 *sasr_3393 = 0x1e;
266 qq = *scmd_3393;
267 *sasr_3393 = 0x1e;
268 *scmd_3393 = q;
269 if (qq != q || qq != 0xff) /* should be read only, all 1's */
270 return -ENODEV;
271 *sasr_3393 = WD_TIMEOUT_PERIOD;
272 q = *scmd_3393;
273 *sasr_3393 = WD_TIMEOUT_PERIOD;
274 *scmd_3393 = ~q;
275 *sasr_3393 = WD_TIMEOUT_PERIOD;
276 qq = *scmd_3393;
277 *sasr_3393 = WD_TIMEOUT_PERIOD;
278 *scmd_3393 = q;
279 if (qq != (~q & 0xff)) /* should be read/write */
280 return -ENODEV;
281#endif /* CHECK_WD33C93 */
390 282
391int gvp11_release(struct Scsi_Host *instance) 283 return 0;
284}
285
286static int __devinit gvp11_probe(struct zorro_dev *z,
287 const struct zorro_device_id *ent)
392{ 288{
393#ifdef MODULE 289 struct Scsi_Host *instance;
394 DMA(instance)->CNTR = 0; 290 unsigned long address;
395 release_mem_region(ZTWO_PADDR(instance->base), 256); 291 int error;
292 unsigned int epc;
293 unsigned int default_dma_xfer_mask;
294 struct gvp11_hostdata *hdata;
295 struct gvp11_scsiregs *regs;
296 wd33c93_regs wdregs;
297
298 default_dma_xfer_mask = ent->driver_data;
299
300 /*
301 * Rumors state that some GVP ram boards use the same product
302 * code as the SCSI controllers. Therefore if the board-size
303 * is not 64KB we asume it is a ram board and bail out.
304 */
305 if (zorro_resource_len(z) != 0x10000)
306 return -ENODEV;
307
308 address = z->resource.start;
309 if (!request_mem_region(address, 256, "wd33c93"))
310 return -EBUSY;
311
312 regs = (struct gvp11_scsiregs *)(ZTWO_VADDR(address));
313
314 error = check_wd33c93(regs);
315 if (error)
316 goto fail_check_or_alloc;
317
318 instance = scsi_host_alloc(&gvp11_scsi_template,
319 sizeof(struct gvp11_hostdata));
320 if (!instance) {
321 error = -ENOMEM;
322 goto fail_check_or_alloc;
323 }
324
325 instance->irq = IRQ_AMIGA_PORTS;
326 instance->unique_id = z->slotaddr;
327
328 regs->secret2 = 1;
329 regs->secret1 = 0;
330 regs->secret3 = 15;
331 while (regs->CNTR & GVP11_DMAC_BUSY)
332 ;
333 regs->CNTR = 0;
334 regs->BANK = 0;
335
336 wdregs.SASR = &regs->SASR;
337 wdregs.SCMD = &regs->SCMD;
338
339 hdata = shost_priv(instance);
340 if (gvp11_xfer_mask)
341 hdata->wh.dma_xfer_mask = gvp11_xfer_mask;
342 else
343 hdata->wh.dma_xfer_mask = default_dma_xfer_mask;
344
345 hdata->wh.no_sync = 0xff;
346 hdata->wh.fast = 0;
347 hdata->wh.dma_mode = CTRL_DMA;
348 hdata->regs = regs;
349
350 /*
351 * Check for 14MHz SCSI clock
352 */
353 epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000);
354 wd33c93_init(instance, wdregs, dma_setup, dma_stop,
355 (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10
356 : WD33C93_FS_12_15);
357
358 error = request_irq(IRQ_AMIGA_PORTS, gvp11_intr, IRQF_SHARED,
359 "GVP11 SCSI", instance);
360 if (error)
361 goto fail_irq;
362
363 regs->CNTR = GVP11_DMAC_INT_ENABLE;
364
365 error = scsi_add_host(instance, NULL);
366 if (error)
367 goto fail_host;
368
369 zorro_set_drvdata(z, instance);
370 scsi_scan_host(instance);
371 return 0;
372
373fail_host:
396 free_irq(IRQ_AMIGA_PORTS, instance); 374 free_irq(IRQ_AMIGA_PORTS, instance);
397#endif 375fail_irq:
398 return 1; 376 scsi_host_put(instance);
377fail_check_or_alloc:
378 release_mem_region(address, 256);
379 return error;
380}
381
382static void __devexit gvp11_remove(struct zorro_dev *z)
383{
384 struct Scsi_Host *instance = zorro_get_drvdata(z);
385 struct gvp11_hostdata *hdata = shost_priv(instance);
386
387 hdata->regs->CNTR = 0;
388 scsi_remove_host(instance);
389 free_irq(IRQ_AMIGA_PORTS, instance);
390 scsi_host_put(instance);
391 release_mem_region(z->resource.start, 256);
392}
393
394 /*
395 * This should (hopefully) be the correct way to identify
396 * all the different GVP SCSI controllers (except for the
397 * SERIES I though).
398 */
399
400static struct zorro_device_id gvp11_zorro_tbl[] __devinitdata = {
401 { ZORRO_PROD_GVP_COMBO_030_R3_SCSI, ~0x00ffffff },
402 { ZORRO_PROD_GVP_SERIES_II, ~0x00ffffff },
403 { ZORRO_PROD_GVP_GFORCE_030_SCSI, ~0x01ffffff },
404 { ZORRO_PROD_GVP_A530_SCSI, ~0x01ffffff },
405 { ZORRO_PROD_GVP_COMBO_030_R4_SCSI, ~0x01ffffff },
406 { ZORRO_PROD_GVP_A1291, ~0x07ffffff },
407 { ZORRO_PROD_GVP_GFORCE_040_SCSI_1, ~0x07ffffff },
408 { 0 }
409};
410MODULE_DEVICE_TABLE(zorro, gvp11_zorro_tbl);
411
412static struct zorro_driver gvp11_driver = {
413 .name = "gvp11",
414 .id_table = gvp11_zorro_tbl,
415 .probe = gvp11_probe,
416 .remove = __devexit_p(gvp11_remove),
417};
418
419static int __init gvp11_init(void)
420{
421 return zorro_register_driver(&gvp11_driver);
422}
423module_init(gvp11_init);
424
425static void __exit gvp11_exit(void)
426{
427 zorro_unregister_driver(&gvp11_driver);
399} 428}
429module_exit(gvp11_exit);
400 430
431MODULE_DESCRIPTION("GVP Series II SCSI");
401MODULE_LICENSE("GPL"); 432MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/gvp11.h b/drivers/scsi/gvp11.h
index e2efdf9601ef..852913cde5dd 100644
--- a/drivers/scsi/gvp11.h
+++ b/drivers/scsi/gvp11.h
@@ -11,9 +11,6 @@
11 11
12#include <linux/types.h> 12#include <linux/types.h>
13 13
14int gvp11_detect(struct scsi_host_template *);
15int gvp11_release(struct Scsi_Host *);
16
17#ifndef CMD_PER_LUN 14#ifndef CMD_PER_LUN
18#define CMD_PER_LUN 2 15#define CMD_PER_LUN 2
19#endif 16#endif
@@ -22,15 +19,13 @@ int gvp11_release(struct Scsi_Host *);
22#define CAN_QUEUE 16 19#define CAN_QUEUE 16
23#endif 20#endif
24 21
25#ifndef HOSTS_C
26
27/* 22/*
28 * if the transfer address ANDed with this results in a non-zero 23 * if the transfer address ANDed with this results in a non-zero
29 * result, then we can't use DMA. 24 * result, then we can't use DMA.
30 */ 25 */
31#define GVP11_XFER_MASK (0xff000001) 26#define GVP11_XFER_MASK (0xff000001)
32 27
33typedef struct { 28struct gvp11_scsiregs {
34 unsigned char pad1[64]; 29 unsigned char pad1[64];
35 volatile unsigned short CNTR; 30 volatile unsigned short CNTR;
36 unsigned char pad2[31]; 31 unsigned char pad2[31];
@@ -46,7 +41,7 @@ typedef struct {
46 volatile unsigned short SP_DMA; 41 volatile unsigned short SP_DMA;
47 volatile unsigned short secret2; /* store 1 here */ 42 volatile unsigned short secret2; /* store 1 here */
48 volatile unsigned short secret3; /* store 15 here */ 43 volatile unsigned short secret3; /* store 15 here */
49} gvp11_scsiregs; 44};
50 45
51/* bits in CNTR */ 46/* bits in CNTR */
52#define GVP11_DMAC_BUSY (1<<0) 47#define GVP11_DMAC_BUSY (1<<0)
@@ -54,6 +49,4 @@ typedef struct {
54#define GVP11_DMAC_INT_ENABLE (1<<3) 49#define GVP11_DMAC_INT_ENABLE (1<<3)
55#define GVP11_DMAC_DIR_WRITE (1<<4) 50#define GVP11_DMAC_DIR_WRITE (1<<4)
56 51
57#endif /* else def HOSTS_C */
58
59#endif /* GVP11_H */ 52#endif /* GVP11_H */
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index 716d1785cda7..c29d0dbb9660 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -16,12 +16,12 @@
16#include <linux/stat.h> 16#include <linux/stat.h>
17 17
18 18
19static struct Scsi_Host *mvme147_host = NULL; 19static irqreturn_t mvme147_intr(int irq, void *data)
20
21static irqreturn_t mvme147_intr(int irq, void *dummy)
22{ 20{
21 struct Scsi_Host *instance = data;
22
23 if (irq == MVME147_IRQ_SCSI_PORT) 23 if (irq == MVME147_IRQ_SCSI_PORT)
24 wd33c93_intr(mvme147_host); 24 wd33c93_intr(instance);
25 else 25 else
26 m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ 26 m147_pcc->dma_intr = 0x89; /* Ack and enable ints */
27 return IRQ_HANDLED; 27 return IRQ_HANDLED;
@@ -29,7 +29,8 @@ static irqreturn_t mvme147_intr(int irq, void *dummy)
29 29
30static int dma_setup(struct scsi_cmnd *cmd, int dir_in) 30static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
31{ 31{
32 struct WD33C93_hostdata *hdata = shost_priv(mvme147_host); 32 struct Scsi_Host *instance = cmd->device->host;
33 struct WD33C93_hostdata *hdata = shost_priv(instance);
33 unsigned char flags = 0x01; 34 unsigned char flags = 0x01;
34 unsigned long addr = virt_to_bus(cmd->SCp.ptr); 35 unsigned long addr = virt_to_bus(cmd->SCp.ptr);
35 36
@@ -66,6 +67,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
66int mvme147_detect(struct scsi_host_template *tpnt) 67int mvme147_detect(struct scsi_host_template *tpnt)
67{ 68{
68 static unsigned char called = 0; 69 static unsigned char called = 0;
70 struct Scsi_Host *instance;
69 wd33c93_regs regs; 71 wd33c93_regs regs;
70 struct WD33C93_hostdata *hdata; 72 struct WD33C93_hostdata *hdata;
71 73
@@ -76,25 +78,25 @@ int mvme147_detect(struct scsi_host_template *tpnt)
76 tpnt->proc_name = "MVME147"; 78 tpnt->proc_name = "MVME147";
77 tpnt->proc_info = &wd33c93_proc_info; 79 tpnt->proc_info = &wd33c93_proc_info;
78 80
79 mvme147_host = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); 81 instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata));
80 if (!mvme147_host) 82 if (!instance)
81 goto err_out; 83 goto err_out;
82 84
83 mvme147_host->base = 0xfffe4000; 85 instance->base = 0xfffe4000;
84 mvme147_host->irq = MVME147_IRQ_SCSI_PORT; 86 instance->irq = MVME147_IRQ_SCSI_PORT;
85 regs.SASR = (volatile unsigned char *)0xfffe4000; 87 regs.SASR = (volatile unsigned char *)0xfffe4000;
86 regs.SCMD = (volatile unsigned char *)0xfffe4001; 88 regs.SCMD = (volatile unsigned char *)0xfffe4001;
87 hdata = shost_priv(mvme147_host); 89 hdata = shost_priv(instance);
88 hdata->no_sync = 0xff; 90 hdata->no_sync = 0xff;
89 hdata->fast = 0; 91 hdata->fast = 0;
90 hdata->dma_mode = CTRL_DMA; 92 hdata->dma_mode = CTRL_DMA;
91 wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10); 93 wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
92 94
93 if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, 95 if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0,
94 "MVME147 SCSI PORT", mvme147_intr)) 96 "MVME147 SCSI PORT", instance))
95 goto err_unregister; 97 goto err_unregister;
96 if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, 98 if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0,
97 "MVME147 SCSI DMA", mvme147_intr)) 99 "MVME147 SCSI DMA", instance))
98 goto err_free_irq; 100 goto err_free_irq;
99#if 0 /* Disabled; causes problems booting */ 101#if 0 /* Disabled; causes problems booting */
100 m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */ 102 m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */
@@ -113,7 +115,7 @@ int mvme147_detect(struct scsi_host_template *tpnt)
113err_free_irq: 115err_free_irq:
114 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); 116 free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr);
115err_unregister: 117err_unregister:
116 scsi_unregister(mvme147_host); 118 scsi_unregister(instance);
117err_out: 119err_out:
118 return 0; 120 return 0;
119} 121}
@@ -132,9 +134,6 @@ static int mvme147_bus_reset(struct scsi_cmnd *cmd)
132 return SUCCESS; 134 return SUCCESS;
133} 135}
134 136
135#define HOSTS_C
136
137#include "mvme147.h"
138 137
139static struct scsi_host_template driver_template = { 138static struct scsi_host_template driver_template = {
140 .proc_name = "MVME147", 139 .proc_name = "MVME147",