Skip to content

Commit

Permalink
maple: fix device detection
Browse files Browse the repository at this point in the history
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: Adrian McMenamin <adrian@mcmen.demon.co.uk>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
  • Loading branch information
Adrian McMenamin authored and Paul Mundt committed Feb 26, 2008
1 parent b7fd095 commit bd49666
Showing 1 changed file with 43 additions and 23 deletions.
66 changes: 43 additions & 23 deletions drivers/sh/maple/maple.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Core maple bus functionality
*
* Copyright (C) 2007 Adrian McMenamin
* Copyright (C) 2007, 2008 Adrian McMenamin
*
* Based on 2.4 code by:
*
Expand All @@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/io.h>
Expand Down Expand Up @@ -54,14 +53,17 @@ static struct device maple_bus;
static int subdevice_map[MAPLE_PORTS];
static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr;
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;

struct maple_device_specify {
int port;
int unit;
};

static bool checked[4];
static struct maple_device *baseunits[4];

/**
* maple_driver_register - register a device driver
* automatically makes the driver bus a maple bus
Expand Down Expand Up @@ -309,11 +311,9 @@ static void maple_attach_driver(struct maple_device *mdev)
else
break;

if (realscan) {
printk(KERN_INFO "Maple device detected: %s\n",
mdev->product_name);
printk(KERN_INFO "Maple device: %s\n", mdev->product_licence);
}
printk(KERN_INFO "Maple device detected: %s\n",
mdev->product_name);
printk(KERN_INFO "Maple device: %s\n", mdev->product_licence);

function = be32_to_cpu(mdev->devinfo.function);

Expand All @@ -323,20 +323,18 @@ static void maple_attach_driver(struct maple_device *mdev)
mdev->driver = &maple_dummy_driver;
sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port);
} else {
if (realscan)
printk(KERN_INFO
"Maple bus at (%d, %d): Function 0x%lX\n",
mdev->port, mdev->unit, function);
printk(KERN_INFO
"Maple bus at (%d, %d): Function 0x%lX\n",
mdev->port, mdev->unit, function);

matched =
bus_for_each_drv(&maple_bus_type, NULL, mdev,
attach_matching_maple_driver);

if (matched == 0) {
/* Driver does not exist yet */
if (realscan)
printk(KERN_INFO
"No maple driver found.\n");
printk(KERN_INFO
"No maple driver found.\n");
mdev->driver = &maple_dummy_driver;
}
sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port,
Expand Down Expand Up @@ -472,9 +470,12 @@ static void maple_response_none(struct maple_device *mdev,
maple_detach_driver(mdev);
return;
}
if (!started) {
printk(KERN_INFO "No maple devices attached to port %d\n",
mdev->port);
if (!started || !fullscan) {
if (checked[mdev->port] == false) {
checked[mdev->port] = true;
printk(KERN_INFO "No maple devices attached"
" to port %d\n", mdev->port);
}
return;
}
maple_clean_submap(mdev);
Expand All @@ -485,8 +486,14 @@ static void maple_response_devinfo(struct maple_device *mdev,
char *recvbuf)
{
char submask;
if ((!started) || (scanning == 2)) {
maple_attach_driver(mdev);
if (!started || (scanning == 2) || !fullscan) {
if ((mdev->unit == 0) && (checked[mdev->port] == false)) {
checked[mdev->port] = true;
maple_attach_driver(mdev);
} else {
if (mdev->unit != 0)
maple_attach_driver(mdev);
}
return;
}
if (mdev->unit == 0) {
Expand All @@ -505,6 +512,7 @@ static void maple_dma_handler(struct work_struct *work)
struct maple_device *dev;
char *recvbuf;
enum maple_code code;
int i;

if (!maple_dma_done())
return;
Expand Down Expand Up @@ -557,6 +565,19 @@ static void maple_dma_handler(struct work_struct *work)
} else
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)
started = 1;
}
Expand Down Expand Up @@ -694,7 +715,9 @@ static int __init maple_bus_init(void)

/* setup maple ports */
for (i = 0; i < MAPLE_PORTS; i++) {
checked[i] = false;
mdev[i] = maple_alloc_dev(i, 0);
baseunits[i] = mdev[i];
if (!mdev[i]) {
while (i-- > 0)
maple_free_dev(mdev[i]);
Expand All @@ -703,12 +726,9 @@ static int __init maple_bus_init(void)
mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO;
mdev[i]->mq->length = 0;
maple_add_packet(mdev[i]->mq);
/* delay aids hardware detection */
mdelay(5);
subdevice_map[i] = 0;
}

realscan = 1;
/* setup maplebus hardware */
maplebus_dma_reset();
/* initial detection */
Expand Down

0 comments on commit bd49666

Please sign in to comment.