Commit bd496669 authored by Adrian McMenamin's avatar Adrian McMenamin Committed by Paul Mundt

maple: fix device detection

The maple bus driver that went into the kernel mainline in September 2007
contained some bugs which were revealed by the update of the kobj code
for the current release series. Unfortunately those bugs also helped
ensure maple devices were properly detected. This patch (against the
current git) now ensures that devices are properly detected again.

(A previous attempt to fix this by delaying initialisation only partially
 fixed this - as became apparent when the bus was fully loaded)
Signed-off-by: default avatarAdrian McMenamin <adrian@mcmen.demon.co.uk>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent b7fd0956
/* /*
* Core maple bus functionality * Core maple bus functionality
* *
* Copyright (C) 2007 Adrian McMenamin * Copyright (C) 2007, 2008 Adrian McMenamin
* *
* Based on 2.4 code by: * Based on 2.4 code by:
* *
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -54,7 +53,7 @@ static struct device maple_bus; ...@@ -54,7 +53,7 @@ static struct device maple_bus;
static int subdevice_map[MAPLE_PORTS]; static int subdevice_map[MAPLE_PORTS];
static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr;
static unsigned long maple_pnp_time; static unsigned long maple_pnp_time;
static int started, scanning, liststatus, realscan; static int started, scanning, liststatus, fullscan;
static struct kmem_cache *maple_queue_cache; static struct kmem_cache *maple_queue_cache;
struct maple_device_specify { struct maple_device_specify {
...@@ -62,6 +61,9 @@ struct maple_device_specify { ...@@ -62,6 +61,9 @@ struct maple_device_specify {
int unit; int unit;
}; };
static bool checked[4];
static struct maple_device *baseunits[4];
/** /**
* maple_driver_register - register a device driver * maple_driver_register - register a device driver
* automatically makes the driver bus a maple bus * automatically makes the driver bus a maple bus
...@@ -309,11 +311,9 @@ static void maple_attach_driver(struct maple_device *mdev) ...@@ -309,11 +311,9 @@ static void maple_attach_driver(struct maple_device *mdev)
else else
break; break;
if (realscan) {
printk(KERN_INFO "Maple device detected: %s\n", printk(KERN_INFO "Maple device detected: %s\n",
mdev->product_name); mdev->product_name);
printk(KERN_INFO "Maple device: %s\n", mdev->product_licence); printk(KERN_INFO "Maple device: %s\n", mdev->product_licence);
}
function = be32_to_cpu(mdev->devinfo.function); function = be32_to_cpu(mdev->devinfo.function);
...@@ -323,7 +323,6 @@ static void maple_attach_driver(struct maple_device *mdev) ...@@ -323,7 +323,6 @@ static void maple_attach_driver(struct maple_device *mdev)
mdev->driver = &maple_dummy_driver; mdev->driver = &maple_dummy_driver;
sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port); sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port);
} else { } else {
if (realscan)
printk(KERN_INFO printk(KERN_INFO
"Maple bus at (%d, %d): Function 0x%lX\n", "Maple bus at (%d, %d): Function 0x%lX\n",
mdev->port, mdev->unit, function); mdev->port, mdev->unit, function);
...@@ -334,7 +333,6 @@ static void maple_attach_driver(struct maple_device *mdev) ...@@ -334,7 +333,6 @@ static void maple_attach_driver(struct maple_device *mdev)
if (matched == 0) { if (matched == 0) {
/* Driver does not exist yet */ /* Driver does not exist yet */
if (realscan)
printk(KERN_INFO printk(KERN_INFO
"No maple driver found.\n"); "No maple driver found.\n");
mdev->driver = &maple_dummy_driver; mdev->driver = &maple_dummy_driver;
...@@ -472,9 +470,12 @@ static void maple_response_none(struct maple_device *mdev, ...@@ -472,9 +470,12 @@ static void maple_response_none(struct maple_device *mdev,
maple_detach_driver(mdev); maple_detach_driver(mdev);
return; return;
} }
if (!started) { if (!started || !fullscan) {
printk(KERN_INFO "No maple devices attached to port %d\n", if (checked[mdev->port] == false) {
mdev->port); checked[mdev->port] = true;
printk(KERN_INFO "No maple devices attached"
" to port %d\n", mdev->port);
}
return; return;
} }
maple_clean_submap(mdev); maple_clean_submap(mdev);
...@@ -485,8 +486,14 @@ static void maple_response_devinfo(struct maple_device *mdev, ...@@ -485,8 +486,14 @@ static void maple_response_devinfo(struct maple_device *mdev,
char *recvbuf) char *recvbuf)
{ {
char submask; char submask;
if ((!started) || (scanning == 2)) { if (!started || (scanning == 2) || !fullscan) {
if ((mdev->unit == 0) && (checked[mdev->port] == false)) {
checked[mdev->port] = true;
maple_attach_driver(mdev); maple_attach_driver(mdev);
} else {
if (mdev->unit != 0)
maple_attach_driver(mdev);
}
return; return;
} }
if (mdev->unit == 0) { if (mdev->unit == 0) {
...@@ -505,6 +512,7 @@ static void maple_dma_handler(struct work_struct *work) ...@@ -505,6 +512,7 @@ static void maple_dma_handler(struct work_struct *work)
struct maple_device *dev; struct maple_device *dev;
char *recvbuf; char *recvbuf;
enum maple_code code; enum maple_code code;
int i;
if (!maple_dma_done()) if (!maple_dma_done())
return; return;
...@@ -557,6 +565,19 @@ static void maple_dma_handler(struct work_struct *work) ...@@ -557,6 +565,19 @@ static void maple_dma_handler(struct work_struct *work)
} else } else
scanning = 0; scanning = 0;
if (!fullscan) {
fullscan = 1;
for (i = 0; i < MAPLE_PORTS; i++) {
if (checked[i] == false) {
fullscan = 0;
dev = baseunits[i];
dev->mq->command =
MAPLE_COMMAND_DEVINFO;
dev->mq->length = 0;
maple_add_packet(dev->mq);
}
}
}
if (started == 0) if (started == 0)
started = 1; started = 1;
} }
...@@ -694,7 +715,9 @@ static int __init maple_bus_init(void) ...@@ -694,7 +715,9 @@ static int __init maple_bus_init(void)
/* setup maple ports */ /* setup maple ports */
for (i = 0; i < MAPLE_PORTS; i++) { for (i = 0; i < MAPLE_PORTS; i++) {
checked[i] = false;
mdev[i] = maple_alloc_dev(i, 0); mdev[i] = maple_alloc_dev(i, 0);
baseunits[i] = mdev[i];
if (!mdev[i]) { if (!mdev[i]) {
while (i-- > 0) while (i-- > 0)
maple_free_dev(mdev[i]); maple_free_dev(mdev[i]);
...@@ -703,12 +726,9 @@ static int __init maple_bus_init(void) ...@@ -703,12 +726,9 @@ static int __init maple_bus_init(void)
mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO; mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO;
mdev[i]->mq->length = 0; mdev[i]->mq->length = 0;
maple_add_packet(mdev[i]->mq); maple_add_packet(mdev[i]->mq);
/* delay aids hardware detection */
mdelay(5);
subdevice_map[i] = 0; subdevice_map[i] = 0;
} }
realscan = 1;
/* setup maplebus hardware */ /* setup maplebus hardware */
maplebus_dma_reset(); maplebus_dma_reset();
/* initial detection */ /* initial detection */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment