aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh/maple/maple.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-26 14:11:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-26 14:11:23 -0400
commit928a726b0e12184729900c076e13dbf1c511c96c (patch)
treef31a7f23c1b511ebb486598cc746786e1821d48c /drivers/sh/maple/maple.c
parent8ff64b539bfd998792614481ccb67139b97075ef (diff)
parenteaeed5d31d8ded02fa0a4b608f57418cc0e65b07 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (96 commits) sh: add support for SMSC Polaris platform sh: fix the HD64461 level-triggered interrupts handling sh: sh-rtc wakeup support sh: sh-rtc invalid time rework sh: sh-rtc carry interrupt rework sh: disallow kexec virtual entry sh: kexec jump: fix for ftrace. sh: kexec: Drop SR.BL bit toggling. sh: add kexec jump support sh: rework kexec segment code sh: simplify kexec vbr code sh: Flush only the needed range when unmapping a VMA. sh: Update debugfs ASID dumping for 16-bit ASID support. sh: tlb-pteaex: Kill off legacy PTEA updates. sh: Support for extended ASIDs on PTEAEX-capable SH-X3 cores. sh: sh7763rdp: Change IRQ number for sh_eth of sh7763rdp sh: espt-giga board support sh: dma: Make G2 DMA configurable. sh: dma: Make PVR2 DMA configurable. sh: Move IRQ multi definition of DMAC to defconfig ...
Diffstat (limited to 'drivers/sh/maple/maple.c')
-rw-r--r--drivers/sh/maple/maple.c472
1 files changed, 239 insertions, 233 deletions
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index 63f0de29aa14..c71bb4b4ce84 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -1,16 +1,10 @@
1/* 1/*
2 * Core maple bus functionality 2 * Core maple bus functionality
3 * 3 *
4 * Copyright (C) 2007, 2008 Adrian McMenamin 4 * Copyright (C) 2007 - 2009 Adrian McMenamin
5 * Copyright (C) 2001 - 2008 Paul Mundt 5 * Copyright (C) 2001 - 2008 Paul Mundt
6 * 6 * Copyright (C) 2000 - 2001 YAEGASHI Takeshi
7 * Based on 2.4 code by:
8 *
9 * Copyright (C) 2000-2001 YAEGASHI Takeshi
10 * Copyright (C) 2001 M. R. Brown 7 * Copyright (C) 2001 M. R. Brown
11 * Copyright (C) 2001 Paul Mundt
12 *
13 * and others.
14 * 8 *
15 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file "COPYING" in the main directory of this archive 10 * License. See the file "COPYING" in the main directory of this archive
@@ -32,7 +26,7 @@
32#include <mach/dma.h> 26#include <mach/dma.h>
33#include <mach/sysasic.h> 27#include <mach/sysasic.h>
34 28
35MODULE_AUTHOR("Yaegashi Takeshi, Paul Mundt, M. R. Brown, Adrian McMenamin"); 29MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
36MODULE_DESCRIPTION("Maple bus driver for Dreamcast"); 30MODULE_DESCRIPTION("Maple bus driver for Dreamcast");
37MODULE_LICENSE("GPL v2"); 31MODULE_LICENSE("GPL v2");
38MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}"); 32MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}");
@@ -49,7 +43,7 @@ static LIST_HEAD(maple_sentq);
49/* mutex to protect queue of waiting packets */ 43/* mutex to protect queue of waiting packets */
50static DEFINE_MUTEX(maple_wlist_lock); 44static DEFINE_MUTEX(maple_wlist_lock);
51 45
52static struct maple_driver maple_dummy_driver; 46static struct maple_driver maple_unsupported_device;
53static struct device maple_bus; 47static struct device maple_bus;
54static int subdevice_map[MAPLE_PORTS]; 48static int subdevice_map[MAPLE_PORTS];
55static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; 49static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr;
@@ -62,8 +56,9 @@ struct maple_device_specify {
62 int unit; 56 int unit;
63}; 57};
64 58
65static bool checked[4]; 59static bool checked[MAPLE_PORTS];
66static struct maple_device *baseunits[4]; 60static bool empty[MAPLE_PORTS];
61static struct maple_device *baseunits[MAPLE_PORTS];
67 62
68/** 63/**
69 * maple_driver_register - register a maple driver 64 * maple_driver_register - register a maple driver
@@ -97,12 +92,20 @@ void maple_driver_unregister(struct maple_driver *drv)
97EXPORT_SYMBOL_GPL(maple_driver_unregister); 92EXPORT_SYMBOL_GPL(maple_driver_unregister);
98 93
99/* set hardware registers to enable next round of dma */ 94/* set hardware registers to enable next round of dma */
100static void maplebus_dma_reset(void) 95static void maple_dma_reset(void)
101{ 96{
102 ctrl_outl(MAPLE_MAGIC, MAPLE_RESET); 97 ctrl_outl(MAPLE_MAGIC, MAPLE_RESET);
103 /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */ 98 /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */
104 ctrl_outl(1, MAPLE_TRIGTYPE); 99 ctrl_outl(1, MAPLE_TRIGTYPE);
105 ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(50000), MAPLE_SPEED); 100 /*
101 * Maple system register
102 * bits 31 - 16 timeout in units of 20nsec
103 * bit 12 hard trigger - set 0 to keep responding to VBLANK
104 * bits 9 - 8 set 00 for 2 Mbps, 01 for 1 Mbps
105 * bits 3 - 0 delay (in 1.3ms) between VBLANK and start of DMA
106 * max delay is 11
107 */
108 ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(0xFFFF), MAPLE_SPEED);
106 ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR); 109 ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR);
107 ctrl_outl(1, MAPLE_ENABLE); 110 ctrl_outl(1, MAPLE_ENABLE);
108} 111}
@@ -134,21 +137,16 @@ static void maple_release_device(struct device *dev)
134{ 137{
135 struct maple_device *mdev; 138 struct maple_device *mdev;
136 struct mapleq *mq; 139 struct mapleq *mq;
137 if (!dev) 140
138 return;
139 mdev = to_maple_dev(dev); 141 mdev = to_maple_dev(dev);
140 mq = mdev->mq; 142 mq = mdev->mq;
141 if (mq) { 143 kmem_cache_free(maple_queue_cache, mq->recvbuf);
142 if (mq->recvbufdcsp) 144 kfree(mq);
143 kmem_cache_free(maple_queue_cache, mq->recvbufdcsp);
144 kfree(mq);
145 mq = NULL;
146 }
147 kfree(mdev); 145 kfree(mdev);
148} 146}
149 147
150/** 148/**
151 * maple_add_packet - add a single instruction to the queue 149 * maple_add_packet - add a single instruction to the maple bus queue
152 * @mdev: maple device 150 * @mdev: maple device
153 * @function: function on device being queried 151 * @function: function on device being queried
154 * @command: maple command to add 152 * @command: maple command to add
@@ -158,68 +156,12 @@ static void maple_release_device(struct device *dev)
158int maple_add_packet(struct maple_device *mdev, u32 function, u32 command, 156int maple_add_packet(struct maple_device *mdev, u32 function, u32 command,
159 size_t length, void *data) 157 size_t length, void *data)
160{ 158{
161 int locking, ret = 0; 159 int ret = 0;
162 void *sendbuf = NULL;
163
164 mutex_lock(&maple_wlist_lock);
165 /* bounce if device already locked */
166 locking = mutex_is_locked(&mdev->mq->mutex);
167 if (locking) {
168 ret = -EBUSY;
169 goto out;
170 }
171
172 mutex_lock(&mdev->mq->mutex);
173
174 if (length) {
175 sendbuf = kmalloc(length * 4, GFP_KERNEL);
176 if (!sendbuf) {
177 mutex_unlock(&mdev->mq->mutex);
178 ret = -ENOMEM;
179 goto out;
180 }
181 ((__be32 *)sendbuf)[0] = cpu_to_be32(function);
182 }
183
184 mdev->mq->command = command;
185 mdev->mq->length = length;
186 if (length > 1)
187 memcpy(sendbuf + 4, data, (length - 1) * 4);
188 mdev->mq->sendbuf = sendbuf;
189
190 list_add(&mdev->mq->list, &maple_waitq);
191out:
192 mutex_unlock(&maple_wlist_lock);
193 return ret;
194}
195EXPORT_SYMBOL_GPL(maple_add_packet);
196
197/**
198 * maple_add_packet_sleeps - add a single instruction to the queue
199 * @mdev: maple device
200 * @function: function on device being queried
201 * @command: maple command to add
202 * @length: length of command string (in 32 bit words)
203 * @data: remainder of command string
204 *
205 * Same as maple_add_packet(), but waits for the lock to become free.
206 */
207int maple_add_packet_sleeps(struct maple_device *mdev, u32 function,
208 u32 command, size_t length, void *data)
209{
210 int locking, ret = 0;
211 void *sendbuf = NULL; 160 void *sendbuf = NULL;
212 161
213 locking = mutex_lock_interruptible(&mdev->mq->mutex);
214 if (locking) {
215 ret = -EIO;
216 goto out;
217 }
218
219 if (length) { 162 if (length) {
220 sendbuf = kmalloc(length * 4, GFP_KERNEL); 163 sendbuf = kzalloc(length * 4, GFP_KERNEL);
221 if (!sendbuf) { 164 if (!sendbuf) {
222 mutex_unlock(&mdev->mq->mutex);
223 ret = -ENOMEM; 165 ret = -ENOMEM;
224 goto out; 166 goto out;
225 } 167 }
@@ -233,38 +175,35 @@ int maple_add_packet_sleeps(struct maple_device *mdev, u32 function,
233 mdev->mq->sendbuf = sendbuf; 175 mdev->mq->sendbuf = sendbuf;
234 176
235 mutex_lock(&maple_wlist_lock); 177 mutex_lock(&maple_wlist_lock);
236 list_add(&mdev->mq->list, &maple_waitq); 178 list_add_tail(&mdev->mq->list, &maple_waitq);
237 mutex_unlock(&maple_wlist_lock); 179 mutex_unlock(&maple_wlist_lock);
238out: 180out:
239 return ret; 181 return ret;
240} 182}
241EXPORT_SYMBOL_GPL(maple_add_packet_sleeps); 183EXPORT_SYMBOL_GPL(maple_add_packet);
242 184
243static struct mapleq *maple_allocq(struct maple_device *mdev) 185static struct mapleq *maple_allocq(struct maple_device *mdev)
244{ 186{
245 struct mapleq *mq; 187 struct mapleq *mq;
246 188
247 mq = kmalloc(sizeof(*mq), GFP_KERNEL); 189 mq = kzalloc(sizeof(*mq), GFP_KERNEL);
248 if (!mq) 190 if (!mq)
249 goto failed_nomem; 191 goto failed_nomem;
250 192
193 INIT_LIST_HEAD(&mq->list);
251 mq->dev = mdev; 194 mq->dev = mdev;
252 mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL); 195 mq->recvbuf = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL);
253 mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp);
254 if (!mq->recvbuf) 196 if (!mq->recvbuf)
255 goto failed_p2; 197 goto failed_p2;
256 /* 198 mq->recvbuf->buf = &((mq->recvbuf->bufx)[0]);
257 * most devices do not need the mutex - but
258 * anything that injects block reads or writes
259 * will rely on it
260 */
261 mutex_init(&mq->mutex);
262 199
263 return mq; 200 return mq;
264 201
265failed_p2: 202failed_p2:
266 kfree(mq); 203 kfree(mq);
267failed_nomem: 204failed_nomem:
205 dev_err(&mdev->dev, "could not allocate memory for device (%d, %d)\n",
206 mdev->port, mdev->unit);
268 return NULL; 207 return NULL;
269} 208}
270 209
@@ -272,12 +211,16 @@ static struct maple_device *maple_alloc_dev(int port, int unit)
272{ 211{
273 struct maple_device *mdev; 212 struct maple_device *mdev;
274 213
214 /* zero this out to avoid kobj subsystem
215 * thinking it has already been registered */
216
275 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 217 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
276 if (!mdev) 218 if (!mdev)
277 return NULL; 219 return NULL;
278 220
279 mdev->port = port; 221 mdev->port = port;
280 mdev->unit = unit; 222 mdev->unit = unit;
223
281 mdev->mq = maple_allocq(mdev); 224 mdev->mq = maple_allocq(mdev);
282 225
283 if (!mdev->mq) { 226 if (!mdev->mq) {
@@ -286,19 +229,14 @@ static struct maple_device *maple_alloc_dev(int port, int unit)
286 } 229 }
287 mdev->dev.bus = &maple_bus_type; 230 mdev->dev.bus = &maple_bus_type;
288 mdev->dev.parent = &maple_bus; 231 mdev->dev.parent = &maple_bus;
232 init_waitqueue_head(&mdev->maple_wait);
289 return mdev; 233 return mdev;
290} 234}
291 235
292static void maple_free_dev(struct maple_device *mdev) 236static void maple_free_dev(struct maple_device *mdev)
293{ 237{
294 if (!mdev) 238 kmem_cache_free(maple_queue_cache, mdev->mq->recvbuf);
295 return; 239 kfree(mdev->mq);
296 if (mdev->mq) {
297 if (mdev->mq->recvbufdcsp)
298 kmem_cache_free(maple_queue_cache,
299 mdev->mq->recvbufdcsp);
300 kfree(mdev->mq);
301 }
302 kfree(mdev); 240 kfree(mdev);
303} 241}
304 242
@@ -320,7 +258,7 @@ static void maple_build_block(struct mapleq *mq)
320 maple_lastptr = maple_sendptr; 258 maple_lastptr = maple_sendptr;
321 259
322 *maple_sendptr++ = (port << 16) | len | 0x80000000; 260 *maple_sendptr++ = (port << 16) | len | 0x80000000;
323 *maple_sendptr++ = PHYSADDR(mq->recvbuf); 261 *maple_sendptr++ = PHYSADDR(mq->recvbuf->buf);
324 *maple_sendptr++ = 262 *maple_sendptr++ =
325 mq->command | (to << 8) | (from << 16) | (len << 24); 263 mq->command | (to << 8) | (from << 16) | (len << 24);
326 while (len-- > 0) 264 while (len-- > 0)
@@ -333,20 +271,28 @@ static void maple_send(void)
333 int i, maple_packets = 0; 271 int i, maple_packets = 0;
334 struct mapleq *mq, *nmq; 272 struct mapleq *mq, *nmq;
335 273
336 if (!list_empty(&maple_sentq)) 274 if (!maple_dma_done())
337 return; 275 return;
276
277 /* disable DMA */
278 ctrl_outl(0, MAPLE_ENABLE);
279
280 if (!list_empty(&maple_sentq))
281 goto finish;
282
338 mutex_lock(&maple_wlist_lock); 283 mutex_lock(&maple_wlist_lock);
339 if (list_empty(&maple_waitq) || !maple_dma_done()) { 284 if (list_empty(&maple_waitq)) {
340 mutex_unlock(&maple_wlist_lock); 285 mutex_unlock(&maple_wlist_lock);
341 return; 286 goto finish;
342 } 287 }
343 mutex_unlock(&maple_wlist_lock); 288
344 maple_lastptr = maple_sendbuf; 289 maple_lastptr = maple_sendbuf;
345 maple_sendptr = maple_sendbuf; 290 maple_sendptr = maple_sendbuf;
346 mutex_lock(&maple_wlist_lock); 291
347 list_for_each_entry_safe(mq, nmq, &maple_waitq, list) { 292 list_for_each_entry_safe(mq, nmq, &maple_waitq, list) {
348 maple_build_block(mq); 293 maple_build_block(mq);
349 list_move(&mq->list, &maple_sentq); 294 list_del_init(&mq->list);
295 list_add_tail(&mq->list, &maple_sentq);
350 if (maple_packets++ > MAPLE_MAXPACKETS) 296 if (maple_packets++ > MAPLE_MAXPACKETS)
351 break; 297 break;
352 } 298 }
@@ -356,10 +302,13 @@ static void maple_send(void)
356 dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE, 302 dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE,
357 PAGE_SIZE, DMA_BIDIRECTIONAL); 303 PAGE_SIZE, DMA_BIDIRECTIONAL);
358 } 304 }
305
306finish:
307 maple_dma_reset();
359} 308}
360 309
361/* check if there is a driver registered likely to match this device */ 310/* check if there is a driver registered likely to match this device */
362static int check_matching_maple_driver(struct device_driver *driver, 311static int maple_check_matching_driver(struct device_driver *driver,
363 void *devptr) 312 void *devptr)
364{ 313{
365 struct maple_driver *maple_drv; 314 struct maple_driver *maple_drv;
@@ -374,10 +323,7 @@ static int check_matching_maple_driver(struct device_driver *driver,
374 323
375static void maple_detach_driver(struct maple_device *mdev) 324static void maple_detach_driver(struct maple_device *mdev)
376{ 325{
377 if (!mdev)
378 return;
379 device_unregister(&mdev->dev); 326 device_unregister(&mdev->dev);
380 mdev = NULL;
381} 327}
382 328
383/* process initial MAPLE_COMMAND_DEVINFO for each device or port */ 329/* process initial MAPLE_COMMAND_DEVINFO for each device or port */
@@ -385,9 +331,9 @@ static void maple_attach_driver(struct maple_device *mdev)
385{ 331{
386 char *p, *recvbuf; 332 char *p, *recvbuf;
387 unsigned long function; 333 unsigned long function;
388 int matched, retval; 334 int matched, error;
389 335
390 recvbuf = mdev->mq->recvbuf; 336 recvbuf = mdev->mq->recvbuf->buf;
391 /* copy the data as individual elements in 337 /* copy the data as individual elements in
392 * case of memory optimisation */ 338 * case of memory optimisation */
393 memcpy(&mdev->devinfo.function, recvbuf + 4, 4); 339 memcpy(&mdev->devinfo.function, recvbuf + 4, 4);
@@ -395,7 +341,6 @@ static void maple_attach_driver(struct maple_device *mdev)
395 memcpy(&mdev->devinfo.area_code, recvbuf + 20, 1); 341 memcpy(&mdev->devinfo.area_code, recvbuf + 20, 1);
396 memcpy(&mdev->devinfo.connector_direction, recvbuf + 21, 1); 342 memcpy(&mdev->devinfo.connector_direction, recvbuf + 21, 1);
397 memcpy(&mdev->devinfo.product_name[0], recvbuf + 22, 30); 343 memcpy(&mdev->devinfo.product_name[0], recvbuf + 22, 30);
398 memcpy(&mdev->devinfo.product_licence[0], recvbuf + 52, 60);
399 memcpy(&mdev->devinfo.standby_power, recvbuf + 112, 2); 344 memcpy(&mdev->devinfo.standby_power, recvbuf + 112, 2);
400 memcpy(&mdev->devinfo.max_power, recvbuf + 114, 2); 345 memcpy(&mdev->devinfo.max_power, recvbuf + 114, 2);
401 memcpy(mdev->product_name, mdev->devinfo.product_name, 30); 346 memcpy(mdev->product_name, mdev->devinfo.product_name, 30);
@@ -414,43 +359,40 @@ static void maple_attach_driver(struct maple_device *mdev)
414 else 359 else
415 break; 360 break;
416 361
417 printk(KERN_INFO "Maple device detected: %s\n",
418 mdev->product_name);
419 printk(KERN_INFO "Maple device: %s\n", mdev->product_licence);
420
421 function = be32_to_cpu(mdev->devinfo.function); 362 function = be32_to_cpu(mdev->devinfo.function);
422 363
364 dev_info(&mdev->dev, "detected %s: function 0x%lX: at (%d, %d)\n",
365 mdev->product_name, function, mdev->port, mdev->unit);
366
423 if (function > 0x200) { 367 if (function > 0x200) {
424 /* Do this silently - as not a real device */ 368 /* Do this silently - as not a real device */
425 function = 0; 369 function = 0;
426 mdev->driver = &maple_dummy_driver; 370 mdev->driver = &maple_unsupported_device;
427 sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port); 371 dev_set_name(&mdev->dev, "%d:0.port", mdev->port);
428 } else { 372 } else {
429 printk(KERN_INFO
430 "Maple bus at (%d, %d): Function 0x%lX\n",
431 mdev->port, mdev->unit, function);
432
433 matched = 373 matched =
434 bus_for_each_drv(&maple_bus_type, NULL, mdev, 374 bus_for_each_drv(&maple_bus_type, NULL, mdev,
435 check_matching_maple_driver); 375 maple_check_matching_driver);
436 376
437 if (matched == 0) { 377 if (matched == 0) {
438 /* Driver does not exist yet */ 378 /* Driver does not exist yet */
439 printk(KERN_INFO 379 dev_info(&mdev->dev, "no driver found\n");
440 "No maple driver found.\n"); 380 mdev->driver = &maple_unsupported_device;
441 mdev->driver = &maple_dummy_driver;
442 } 381 }
443 sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port, 382
444 mdev->unit, function); 383 dev_set_name(&mdev->dev, "%d:0%d.%lX", mdev->port,
384 mdev->unit, function);
445 } 385 }
386
446 mdev->function = function; 387 mdev->function = function;
447 mdev->dev.release = &maple_release_device; 388 mdev->dev.release = &maple_release_device;
448 retval = device_register(&mdev->dev); 389
449 if (retval) { 390 atomic_set(&mdev->busy, 0);
450 printk(KERN_INFO 391 error = device_register(&mdev->dev);
451 "Maple bus: Attempt to register device" 392 if (error) {
452 " (%x, %x) failed.\n", 393 dev_warn(&mdev->dev, "could not register device at"
453 mdev->port, mdev->unit); 394 " (%d, %d), with error 0x%X\n", mdev->unit,
395 mdev->port, error);
454 maple_free_dev(mdev); 396 maple_free_dev(mdev);
455 mdev = NULL; 397 mdev = NULL;
456 return; 398 return;
@@ -462,7 +404,7 @@ static void maple_attach_driver(struct maple_device *mdev)
462 * port and unit then return 1 - allows identification 404 * port and unit then return 1 - allows identification
463 * of which devices need to be attached or detached 405 * of which devices need to be attached or detached
464 */ 406 */
465static int detach_maple_device(struct device *device, void *portptr) 407static int check_maple_device(struct device *device, void *portptr)
466{ 408{
467 struct maple_device_specify *ds; 409 struct maple_device_specify *ds;
468 struct maple_device *mdev; 410 struct maple_device *mdev;
@@ -477,21 +419,25 @@ static int detach_maple_device(struct device *device, void *portptr)
477static int setup_maple_commands(struct device *device, void *ignored) 419static int setup_maple_commands(struct device *device, void *ignored)
478{ 420{
479 int add; 421 int add;
480 struct maple_device *maple_dev = to_maple_dev(device); 422 struct maple_device *mdev = to_maple_dev(device);
481 423 if (mdev->interval > 0 && atomic_read(&mdev->busy) == 0 &&
482 if ((maple_dev->interval > 0) 424 time_after(jiffies, mdev->when)) {
483 && time_after(jiffies, maple_dev->when)) { 425 /* bounce if we cannot add */
484 /* bounce if we cannot lock */ 426 add = maple_add_packet(mdev,
485 add = maple_add_packet(maple_dev, 427 be32_to_cpu(mdev->devinfo.function),
486 be32_to_cpu(maple_dev->devinfo.function),
487 MAPLE_COMMAND_GETCOND, 1, NULL); 428 MAPLE_COMMAND_GETCOND, 1, NULL);
488 if (!add) 429 if (!add)
489 maple_dev->when = jiffies + maple_dev->interval; 430 mdev->when = jiffies + mdev->interval;
490 } else { 431 } else {
491 if (time_after(jiffies, maple_pnp_time)) 432 if (time_after(jiffies, maple_pnp_time))
492 /* This will also bounce */ 433 /* Ensure we don't have block reads and devinfo
493 maple_add_packet(maple_dev, 0, 434 * calls interfering with one another - so flag the
494 MAPLE_COMMAND_DEVINFO, 0, NULL); 435 * device as busy */
436 if (atomic_read(&mdev->busy) == 0) {
437 atomic_set(&mdev->busy, 1);
438 maple_add_packet(mdev, 0,
439 MAPLE_COMMAND_DEVINFO, 0, NULL);
440 }
495 } 441 }
496 return 0; 442 return 0;
497} 443}
@@ -499,29 +445,50 @@ static int setup_maple_commands(struct device *device, void *ignored)
499/* VBLANK bottom half - implemented via workqueue */ 445/* VBLANK bottom half - implemented via workqueue */
500static void maple_vblank_handler(struct work_struct *work) 446static void maple_vblank_handler(struct work_struct *work)
501{ 447{
502 if (!list_empty(&maple_sentq) || !maple_dma_done()) 448 int x, locking;
449 struct maple_device *mdev;
450
451 if (!maple_dma_done())
503 return; 452 return;
504 453
505 ctrl_outl(0, MAPLE_ENABLE); 454 ctrl_outl(0, MAPLE_ENABLE);
506 455
456 if (!list_empty(&maple_sentq))
457 goto finish;
458
459 /*
460 * Set up essential commands - to fetch data and
461 * check devices are still present
462 */
507 bus_for_each_dev(&maple_bus_type, NULL, NULL, 463 bus_for_each_dev(&maple_bus_type, NULL, NULL,
508 setup_maple_commands); 464 setup_maple_commands);
465
466 if (time_after(jiffies, maple_pnp_time)) {
467 /*
468 * Scan the empty ports - bus is flakey and may have
469 * mis-reported emptyness
470 */
471 for (x = 0; x < MAPLE_PORTS; x++) {
472 if (checked[x] && empty[x]) {
473 mdev = baseunits[x];
474 if (!mdev)
475 break;
476 atomic_set(&mdev->busy, 1);
477 locking = maple_add_packet(mdev, 0,
478 MAPLE_COMMAND_DEVINFO, 0, NULL);
479 if (!locking)
480 break;
481 }
482 }
509 483
510 if (time_after(jiffies, maple_pnp_time))
511 maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL; 484 maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL;
512
513 mutex_lock(&maple_wlist_lock);
514 if (!list_empty(&maple_waitq) && list_empty(&maple_sentq)) {
515 mutex_unlock(&maple_wlist_lock);
516 maple_send();
517 } else {
518 mutex_unlock(&maple_wlist_lock);
519 } 485 }
520 486
521 maplebus_dma_reset(); 487finish:
488 maple_send();
522} 489}
523 490
524/* handle devices added via hotplugs - placing them on queue for DEVINFO*/ 491/* handle devices added via hotplugs - placing them on queue for DEVINFO */
525static void maple_map_subunits(struct maple_device *mdev, int submask) 492static void maple_map_subunits(struct maple_device *mdev, int submask)
526{ 493{
527 int retval, k, devcheck; 494 int retval, k, devcheck;
@@ -533,7 +500,7 @@ static void maple_map_subunits(struct maple_device *mdev, int submask)
533 ds.unit = k + 1; 500 ds.unit = k + 1;
534 retval = 501 retval =
535 bus_for_each_dev(&maple_bus_type, NULL, &ds, 502 bus_for_each_dev(&maple_bus_type, NULL, &ds,
536 detach_maple_device); 503 check_maple_device);
537 if (retval) { 504 if (retval) {
538 submask = submask >> 1; 505 submask = submask >> 1;
539 continue; 506 continue;
@@ -543,6 +510,7 @@ static void maple_map_subunits(struct maple_device *mdev, int submask)
543 mdev_add = maple_alloc_dev(mdev->port, k + 1); 510 mdev_add = maple_alloc_dev(mdev->port, k + 1);
544 if (!mdev_add) 511 if (!mdev_add)
545 return; 512 return;
513 atomic_set(&mdev_add->busy, 1);
546 maple_add_packet(mdev_add, 0, MAPLE_COMMAND_DEVINFO, 514 maple_add_packet(mdev_add, 0, MAPLE_COMMAND_DEVINFO,
547 0, NULL); 515 0, NULL);
548 /* mark that we are checking sub devices */ 516 /* mark that we are checking sub devices */
@@ -564,27 +532,45 @@ static void maple_clean_submap(struct maple_device *mdev)
564} 532}
565 533
566/* handle empty port or hotplug removal */ 534/* handle empty port or hotplug removal */
567static void maple_response_none(struct maple_device *mdev, 535static void maple_response_none(struct maple_device *mdev)
568 struct mapleq *mq) 536{
569{ 537 maple_clean_submap(mdev);
570 if (mdev->unit != 0) { 538
571 list_del(&mq->list); 539 if (likely(mdev->unit != 0)) {
572 maple_clean_submap(mdev); 540 /*
573 printk(KERN_INFO 541 * Block devices play up
574 "Maple bus device detaching at (%d, %d)\n", 542 * and give the impression they have
575 mdev->port, mdev->unit); 543 * been removed even when still in place or
544 * trip the mtd layer when they have
545 * really gone - this code traps that eventuality
546 * and ensures we aren't overloaded with useless
547 * error messages
548 */
549 if (mdev->can_unload) {
550 if (!mdev->can_unload(mdev)) {
551 atomic_set(&mdev->busy, 2);
552 wake_up(&mdev->maple_wait);
553 return;
554 }
555 }
556
557 dev_info(&mdev->dev, "detaching device at (%d, %d)\n",
558 mdev->port, mdev->unit);
576 maple_detach_driver(mdev); 559 maple_detach_driver(mdev);
577 return; 560 return;
578 } 561 } else {
579 if (!started || !fullscan) { 562 if (!started || !fullscan) {
580 if (checked[mdev->port] == false) { 563 if (checked[mdev->port] == false) {
581 checked[mdev->port] = true; 564 checked[mdev->port] = true;
582 printk(KERN_INFO "No maple devices attached" 565 empty[mdev->port] = true;
583 " to port %d\n", mdev->port); 566 dev_info(&mdev->dev, "no devices"
567 " to port %d\n", mdev->port);
568 }
569 return;
584 } 570 }
585 return;
586 } 571 }
587 maple_clean_submap(mdev); 572 /* Some hardware devices generate false detach messages on unit 0 */
573 atomic_set(&mdev->busy, 0);
588} 574}
589 575
590/* preprocess hotplugs or scans */ 576/* preprocess hotplugs or scans */
@@ -599,8 +585,11 @@ static void maple_response_devinfo(struct maple_device *mdev,
599 } else { 585 } else {
600 if (mdev->unit != 0) 586 if (mdev->unit != 0)
601 maple_attach_driver(mdev); 587 maple_attach_driver(mdev);
588 if (mdev->unit == 0) {
589 empty[mdev->port] = false;
590 maple_attach_driver(mdev);
591 }
602 } 592 }
603 return;
604 } 593 }
605 if (mdev->unit == 0) { 594 if (mdev->unit == 0) {
606 submask = recvbuf[2] & 0x1F; 595 submask = recvbuf[2] & 0x1F;
@@ -611,6 +600,17 @@ static void maple_response_devinfo(struct maple_device *mdev,
611 } 600 }
612} 601}
613 602
603static void maple_response_fileerr(struct maple_device *mdev, void *recvbuf)
604{
605 if (mdev->fileerr_handler) {
606 mdev->fileerr_handler(mdev, recvbuf);
607 return;
608 } else
609 dev_warn(&mdev->dev, "device at (%d, %d) reports"
610 "file error 0x%X\n", mdev->port, mdev->unit,
611 ((int *)recvbuf)[1]);
612}
613
614static void maple_port_rescan(void) 614static void maple_port_rescan(void)
615{ 615{
616 int i; 616 int i;
@@ -621,12 +621,6 @@ static void maple_port_rescan(void)
621 if (checked[i] == false) { 621 if (checked[i] == false) {
622 fullscan = 0; 622 fullscan = 0;
623 mdev = baseunits[i]; 623 mdev = baseunits[i];
624 /*
625 * test lock in case scan has failed
626 * but device is still locked
627 */
628 if (mutex_is_locked(&mdev->mq->mutex))
629 mutex_unlock(&mdev->mq->mutex);
630 maple_add_packet(mdev, 0, MAPLE_COMMAND_DEVINFO, 624 maple_add_packet(mdev, 0, MAPLE_COMMAND_DEVINFO,
631 0, NULL); 625 0, NULL);
632 } 626 }
@@ -637,7 +631,7 @@ static void maple_port_rescan(void)
637static void maple_dma_handler(struct work_struct *work) 631static void maple_dma_handler(struct work_struct *work)
638{ 632{
639 struct mapleq *mq, *nmq; 633 struct mapleq *mq, *nmq;
640 struct maple_device *dev; 634 struct maple_device *mdev;
641 char *recvbuf; 635 char *recvbuf;
642 enum maple_code code; 636 enum maple_code code;
643 637
@@ -646,43 +640,56 @@ static void maple_dma_handler(struct work_struct *work)
646 ctrl_outl(0, MAPLE_ENABLE); 640 ctrl_outl(0, MAPLE_ENABLE);
647 if (!list_empty(&maple_sentq)) { 641 if (!list_empty(&maple_sentq)) {
648 list_for_each_entry_safe(mq, nmq, &maple_sentq, list) { 642 list_for_each_entry_safe(mq, nmq, &maple_sentq, list) {
649 recvbuf = mq->recvbuf; 643 mdev = mq->dev;
644 recvbuf = mq->recvbuf->buf;
645 dma_cache_sync(&mdev->dev, recvbuf, 0x400,
646 DMA_FROM_DEVICE);
650 code = recvbuf[0]; 647 code = recvbuf[0];
651 dev = mq->dev;
652 kfree(mq->sendbuf); 648 kfree(mq->sendbuf);
653 mutex_unlock(&mq->mutex);
654 list_del_init(&mq->list); 649 list_del_init(&mq->list);
655
656 switch (code) { 650 switch (code) {
657 case MAPLE_RESPONSE_NONE: 651 case MAPLE_RESPONSE_NONE:
658 maple_response_none(dev, mq); 652 maple_response_none(mdev);
659 break; 653 break;
660 654
661 case MAPLE_RESPONSE_DEVINFO: 655 case MAPLE_RESPONSE_DEVINFO:
662 maple_response_devinfo(dev, recvbuf); 656 maple_response_devinfo(mdev, recvbuf);
657 atomic_set(&mdev->busy, 0);
663 break; 658 break;
664 659
665 case MAPLE_RESPONSE_DATATRF: 660 case MAPLE_RESPONSE_DATATRF:
666 if (dev->callback) 661 if (mdev->callback)
667 dev->callback(mq); 662 mdev->callback(mq);
663 atomic_set(&mdev->busy, 0);
664 wake_up(&mdev->maple_wait);
668 break; 665 break;
669 666
670 case MAPLE_RESPONSE_FILEERR: 667 case MAPLE_RESPONSE_FILEERR:
668 maple_response_fileerr(mdev, recvbuf);
669 atomic_set(&mdev->busy, 0);
670 wake_up(&mdev->maple_wait);
671 break;
672
671 case MAPLE_RESPONSE_AGAIN: 673 case MAPLE_RESPONSE_AGAIN:
672 case MAPLE_RESPONSE_BADCMD: 674 case MAPLE_RESPONSE_BADCMD:
673 case MAPLE_RESPONSE_BADFUNC: 675 case MAPLE_RESPONSE_BADFUNC:
674 printk(KERN_DEBUG 676 dev_warn(&mdev->dev, "non-fatal error"
675 "Maple non-fatal error 0x%X\n", 677 " 0x%X at (%d, %d)\n", code,
676 code); 678 mdev->port, mdev->unit);
679 atomic_set(&mdev->busy, 0);
677 break; 680 break;
678 681
679 case MAPLE_RESPONSE_ALLINFO: 682 case MAPLE_RESPONSE_ALLINFO:
680 printk(KERN_DEBUG 683 dev_notice(&mdev->dev, "extended"
681 "Maple - extended device information" 684 " device information request for (%d, %d)"
682 " not supported\n"); 685 " but call is not supported\n", mdev->port,
686 mdev->unit);
687 atomic_set(&mdev->busy, 0);
683 break; 688 break;
684 689
685 case MAPLE_RESPONSE_OK: 690 case MAPLE_RESPONSE_OK:
691 atomic_set(&mdev->busy, 0);
692 wake_up(&mdev->maple_wait);
686 break; 693 break;
687 694
688 default: 695 default:
@@ -699,20 +706,19 @@ static void maple_dma_handler(struct work_struct *work)
699 if (!fullscan) 706 if (!fullscan)
700 maple_port_rescan(); 707 maple_port_rescan();
701 /* mark that we have been through the first scan */ 708 /* mark that we have been through the first scan */
702 if (started == 0) 709 started = 1;
703 started = 1;
704 } 710 }
705 maplebus_dma_reset(); 711 maple_send();
706} 712}
707 713
708static irqreturn_t maplebus_dma_interrupt(int irq, void *dev_id) 714static irqreturn_t maple_dma_interrupt(int irq, void *dev_id)
709{ 715{
710 /* Load everything into the bottom half */ 716 /* Load everything into the bottom half */
711 schedule_work(&maple_dma_process); 717 schedule_work(&maple_dma_process);
712 return IRQ_HANDLED; 718 return IRQ_HANDLED;
713} 719}
714 720
715static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id) 721static irqreturn_t maple_vblank_interrupt(int irq, void *dev_id)
716{ 722{
717 schedule_work(&maple_vblank_process); 723 schedule_work(&maple_vblank_process);
718 return IRQ_HANDLED; 724 return IRQ_HANDLED;
@@ -720,14 +726,14 @@ static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id)
720 726
721static int maple_set_dma_interrupt_handler(void) 727static int maple_set_dma_interrupt_handler(void)
722{ 728{
723 return request_irq(HW_EVENT_MAPLE_DMA, maplebus_dma_interrupt, 729 return request_irq(HW_EVENT_MAPLE_DMA, maple_dma_interrupt,
724 IRQF_SHARED, "maple bus DMA", &maple_dummy_driver); 730 IRQF_SHARED, "maple bus DMA", &maple_unsupported_device);
725} 731}
726 732
727static int maple_set_vblank_interrupt_handler(void) 733static int maple_set_vblank_interrupt_handler(void)
728{ 734{
729 return request_irq(HW_EVENT_VSYNC, maplebus_vblank_interrupt, 735 return request_irq(HW_EVENT_VSYNC, maple_vblank_interrupt,
730 IRQF_SHARED, "maple bus VBLANK", &maple_dummy_driver); 736 IRQF_SHARED, "maple bus VBLANK", &maple_unsupported_device);
731} 737}
732 738
733static int maple_get_dma_buffer(void) 739static int maple_get_dma_buffer(void)
@@ -740,7 +746,7 @@ static int maple_get_dma_buffer(void)
740 return 0; 746 return 0;
741} 747}
742 748
743static int match_maple_bus_driver(struct device *devptr, 749static int maple_match_bus_driver(struct device *devptr,
744 struct device_driver *drvptr) 750 struct device_driver *drvptr)
745{ 751{
746 struct maple_driver *maple_drv = to_maple_driver(drvptr); 752 struct maple_driver *maple_drv = to_maple_driver(drvptr);
@@ -765,22 +771,24 @@ static void maple_bus_release(struct device *dev)
765{ 771{
766} 772}
767 773
768static struct maple_driver maple_dummy_driver = { 774static struct maple_driver maple_unsupported_device = {
769 .drv = { 775 .drv = {
770 .name = "maple_dummy_driver", 776 .name = "maple_unsupported_device",
771 .bus = &maple_bus_type, 777 .bus = &maple_bus_type,
772 }, 778 },
773}; 779};
774 780/**
781 * maple_bus_type - core maple bus structure
782 */
775struct bus_type maple_bus_type = { 783struct bus_type maple_bus_type = {
776 .name = "maple", 784 .name = "maple",
777 .match = match_maple_bus_driver, 785 .match = maple_match_bus_driver,
778 .uevent = maple_bus_uevent, 786 .uevent = maple_bus_uevent,
779}; 787};
780EXPORT_SYMBOL_GPL(maple_bus_type); 788EXPORT_SYMBOL_GPL(maple_bus_type);
781 789
782static struct device maple_bus = { 790static struct device maple_bus = {
783 .bus_id = "maple", 791 .init_name = "maple",
784 .release = maple_bus_release, 792 .release = maple_bus_release,
785}; 793};
786 794
@@ -788,7 +796,8 @@ static int __init maple_bus_init(void)
788{ 796{
789 int retval, i; 797 int retval, i;
790 struct maple_device *mdev[MAPLE_PORTS]; 798 struct maple_device *mdev[MAPLE_PORTS];
791 ctrl_outl(0, MAPLE_STATE); 799
800 ctrl_outl(0, MAPLE_ENABLE);
792 801
793 retval = device_register(&maple_bus); 802 retval = device_register(&maple_bus);
794 if (retval) 803 if (retval)
@@ -798,36 +807,33 @@ static int __init maple_bus_init(void)
798 if (retval) 807 if (retval)
799 goto cleanup_device; 808 goto cleanup_device;
800 809
801 retval = driver_register(&maple_dummy_driver.drv); 810 retval = driver_register(&maple_unsupported_device.drv);
802 if (retval) 811 if (retval)
803 goto cleanup_bus; 812 goto cleanup_bus;
804 813
805 /* allocate memory for maple bus dma */ 814 /* allocate memory for maple bus dma */
806 retval = maple_get_dma_buffer(); 815 retval = maple_get_dma_buffer();
807 if (retval) { 816 if (retval) {
808 printk(KERN_INFO 817 dev_err(&maple_bus, "failed to allocate DMA buffers\n");
809 "Maple bus: Failed to allocate Maple DMA buffers\n");
810 goto cleanup_basic; 818 goto cleanup_basic;
811 } 819 }
812 820
813 /* set up DMA interrupt handler */ 821 /* set up DMA interrupt handler */
814 retval = maple_set_dma_interrupt_handler(); 822 retval = maple_set_dma_interrupt_handler();
815 if (retval) { 823 if (retval) {
816 printk(KERN_INFO 824 dev_err(&maple_bus, "bus failed to grab maple "
817 "Maple bus: Failed to grab maple DMA IRQ\n"); 825 "DMA IRQ\n");
818 goto cleanup_dma; 826 goto cleanup_dma;
819 } 827 }
820 828
821 /* set up VBLANK interrupt handler */ 829 /* set up VBLANK interrupt handler */
822 retval = maple_set_vblank_interrupt_handler(); 830 retval = maple_set_vblank_interrupt_handler();
823 if (retval) { 831 if (retval) {
824 printk(KERN_INFO "Maple bus: Failed to grab VBLANK IRQ\n"); 832 dev_err(&maple_bus, "bus failed to grab VBLANK IRQ\n");
825 goto cleanup_irq; 833 goto cleanup_irq;
826 } 834 }
827 835
828 maple_queue_cache = 836 maple_queue_cache = KMEM_CACHE(maple_buffer, SLAB_HWCACHE_ALIGN);
829 kmem_cache_create("maple_queue_cache", 0x400, 0,
830 SLAB_HWCACHE_ALIGN, NULL);
831 837
832 if (!maple_queue_cache) 838 if (!maple_queue_cache)
833 goto cleanup_bothirqs; 839 goto cleanup_bothirqs;
@@ -838,23 +844,23 @@ static int __init maple_bus_init(void)
838 /* setup maple ports */ 844 /* setup maple ports */
839 for (i = 0; i < MAPLE_PORTS; i++) { 845 for (i = 0; i < MAPLE_PORTS; i++) {
840 checked[i] = false; 846 checked[i] = false;
847 empty[i] = false;
841 mdev[i] = maple_alloc_dev(i, 0); 848 mdev[i] = maple_alloc_dev(i, 0);
842 baseunits[i] = mdev[i];
843 if (!mdev[i]) { 849 if (!mdev[i]) {
844 while (i-- > 0) 850 while (i-- > 0)
845 maple_free_dev(mdev[i]); 851 maple_free_dev(mdev[i]);
846 goto cleanup_cache; 852 goto cleanup_cache;
847 } 853 }
854 baseunits[i] = mdev[i];
855 atomic_set(&mdev[i]->busy, 1);
848 maple_add_packet(mdev[i], 0, MAPLE_COMMAND_DEVINFO, 0, NULL); 856 maple_add_packet(mdev[i], 0, MAPLE_COMMAND_DEVINFO, 0, NULL);
849 subdevice_map[i] = 0; 857 subdevice_map[i] = 0;
850 } 858 }
851 859
852 /* setup maplebus hardware */ 860 maple_pnp_time = jiffies + HZ;
853 maplebus_dma_reset(); 861 /* prepare initial queue */
854 /* initial detection */
855 maple_send(); 862 maple_send();
856 maple_pnp_time = jiffies; 863 dev_info(&maple_bus, "bus core now registered\n");
857 printk(KERN_INFO "Maple bus core now registered.\n");
858 864
859 return 0; 865 return 0;
860 866
@@ -871,7 +877,7 @@ cleanup_dma:
871 free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES); 877 free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES);
872 878
873cleanup_basic: 879cleanup_basic:
874 driver_unregister(&maple_dummy_driver.drv); 880 driver_unregister(&maple_unsupported_device.drv);
875 881
876cleanup_bus: 882cleanup_bus:
877 bus_unregister(&maple_bus_type); 883 bus_unregister(&maple_bus_type);
@@ -880,7 +886,7 @@ cleanup_device:
880 device_unregister(&maple_bus); 886 device_unregister(&maple_bus);
881 887
882cleanup: 888cleanup:
883 printk(KERN_INFO "Maple bus registration failed\n"); 889 printk(KERN_ERR "Maple bus registration failed\n");
884 return retval; 890 return retval;
885} 891}
886/* Push init to later to ensure hardware gets detected */ 892/* Push init to later to ensure hardware gets detected */