From: Adrian McMenamin <adrian@newgolddream.dyndns.info>
To: dwmw2@infradead.org, Greg KH <greg@kroah.com>,
Paul Mundt <lethal@linux-sh.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
linux-sh <linux-sh@vger.kernel.org>,
linux-mtd@vger.kernel.org
Subject: [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device
Date: Tue, 18 Mar 2008 22:49:14 +0000 [thread overview]
Message-ID: <1205880554.6250.25.camel@localhost.localdomain> (raw)
In-Reply-To: <1205879413.6250.13.camel@localhost.localdomain>
These patches update the maple bus driver with a semaphore to allow
other maple drivers to inject arbitrary packets (eg block reads and
writes) into the maple bus packet stream - so allowing support for the
VMU (and, eventually, other maple devices).
The patches also ensure that the maple bus driver properly supports the
device model through probing.
Signed-off-by: Adrian McMenamin <adrian@mcmen.demon.co.uk>
---
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index 617efb1..57a118a 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -47,13 +47,14 @@ static LIST_HEAD(maple_waitq);
static LIST_HEAD(maple_sentq);
static DEFINE_MUTEX(maple_list_lock);
+static DEFINE_MUTEX(maple_wlist_lock);
static struct maple_driver maple_dummy_driver;
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, fullscan;
+static int started, scanning, fullscan;
static struct kmem_cache *maple_queue_cache;
struct maple_device_specify {
@@ -135,9 +136,9 @@ static void maple_release_device(struct device *dev)
*/
void maple_add_packet(struct mapleq *mq)
{
- mutex_lock(&maple_list_lock);
+ mutex_lock(&maple_wlist_lock);
list_add(&mq->list, &maple_waitq);
- mutex_unlock(&maple_list_lock);
+ mutex_unlock(&maple_wlist_lock);
}
EXPORT_SYMBOL_GPL(maple_add_packet);
@@ -147,17 +148,21 @@ static struct mapleq *maple_allocq(struct maple_device *mdev)
mq = kmalloc(sizeof(*mq), GFP_KERNEL);
if (!mq)
- return NULL;
+ goto failed_nomem;
mq->dev = mdev;
mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL);
mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp);
- if (!mq->recvbuf) {
- kfree(mq);
- return NULL;
- }
+ if (!mq->recvbuf)
+ goto failed_p2;
+ init_MUTEX(&mq->sem);
return mq;
+
+failed_p2:
+ kfree(mq);
+failed_nomem:
+ return NULL;
}
static struct maple_device *maple_alloc_dev(int port, int unit)
@@ -178,7 +183,6 @@ static struct maple_device *maple_alloc_dev(int port, int unit)
}
mdev->dev.bus = &maple_bus_type;
mdev->dev.parent = &maple_bus;
- mdev->function = 0;
return mdev;
}
@@ -216,8 +220,7 @@ static void maple_build_block(struct mapleq *mq)
*maple_sendptr++ = PHYSADDR(mq->recvbuf);
*maple_sendptr++ mq->command | (to << 8) | (from << 16) | (len << 24);
-
- while (len-- > 0)
+ while (len-- > 0)
*maple_sendptr++ = *lsendbuf++;
}
@@ -230,16 +233,24 @@ static void maple_send(void)
if (!list_empty(&maple_sentq))
return;
- if (list_empty(&maple_waitq) || !maple_dma_done())
+ mutex_lock(&maple_wlist_lock);
+ if (list_empty(&maple_waitq) || !maple_dma_done()) {
+ mutex_unlock(&maple_wlist_lock);
return;
+ }
+ mutex_unlock(&maple_wlist_lock);
maple_packets = 0;
maple_sendptr = maple_lastptr = maple_sendbuf;
- list_for_each_entry_safe(mq, nmq, &maple_waitq, list) {
+ mutex_lock(&maple_list_lock);
+ mutex_lock(&maple_wlist_lock);
+ list_for_each_entry_safe(mq, nmq, &maple_waitq, list) {
maple_build_block(mq);
list_move(&mq->list, &maple_sentq);
- if (maple_packets++ > MAPLE_MAXPACKETS)
+ if (maple_packets++ > MAPLE_MAXPACKETS)
break;
}
+ mutex_unlock(&maple_wlist_lock);
+ mutex_unlock(&maple_list_lock);
if (maple_packets > 0) {
for (i = 0; i < (1 << MAPLE_DMA_PAGES); i++)
dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE,
@@ -247,7 +258,8 @@ static void maple_send(void)
}
}
-static int attach_matching_maple_driver(struct device_driver *driver,
+/* check if there is a driver registered likely to match this device */
+static int check_matching_maple_driver(struct device_driver *driver,
void *devptr)
{
struct maple_driver *maple_drv;
@@ -255,12 +267,8 @@ static int attach_matching_maple_driver(struct device_driver *driver,
mdev = devptr;
maple_drv = to_maple_driver(driver);
- if (mdev->devinfo.function & be32_to_cpu(maple_drv->function)) {
- if (maple_drv->connect(mdev) = 0) {
- mdev->driver = maple_drv;
- return 1;
- }
- }
+ if (mdev->devinfo.function & cpu_to_be32(maple_drv->function))
+ return 1;
return 0;
}
@@ -268,11 +276,6 @@ static void maple_detach_driver(struct maple_device *mdev)
{
if (!mdev)
return;
- if (mdev->driver) {
- if (mdev->driver->disconnect)
- mdev->driver->disconnect(mdev);
- }
- mdev->driver = NULL;
device_unregister(&mdev->dev);
mdev = NULL;
}
@@ -328,8 +331,8 @@ static void maple_attach_driver(struct maple_device *mdev)
mdev->port, mdev->unit, function);
matched - bus_for_each_drv(&maple_bus_type, NULL, mdev,
- attach_matching_maple_driver);
+ bus_for_each_drv(&maple_bus_type, NULL, mdev,
+ check_matching_maple_driver);
if (matched = 0) {
/* Driver does not exist yet */
@@ -342,7 +345,7 @@ static void maple_attach_driver(struct maple_device *mdev)
}
mdev->function = function;
mdev->dev.release = &maple_release_device;
- retval = device_register(&mdev->dev);
+ retval = device_register(&mdev->dev);
if (retval) {
printk(KERN_INFO
"Maple bus: Attempt to register device"
@@ -377,18 +380,20 @@ static int setup_maple_commands(struct device *device, void *ignored)
if ((maple_dev->interval > 0)
&& time_after(jiffies, maple_dev->when)) {
+ if (down_trylock(&maple_dev->mq->sem))
+ return 0;
maple_dev->when = jiffies + maple_dev->interval;
maple_dev->mq->command = MAPLE_COMMAND_GETCOND;
maple_dev->mq->sendbuf = &maple_dev->function;
maple_dev->mq->length = 1;
maple_add_packet(maple_dev->mq);
- liststatus++;
} else {
if (time_after(jiffies, maple_pnp_time)) {
+ if (down_trylock(&maple_dev->mq->sem))
+ return -1;
maple_dev->mq->command = MAPLE_COMMAND_DEVINFO;
maple_dev->mq->length = 0;
maple_add_packet(maple_dev->mq);
- liststatus++;
}
}
@@ -398,32 +403,38 @@ static int setup_maple_commands(struct device *device, void *ignored)
/* VBLANK bottom half - implemented via workqueue */
static void maple_vblank_handler(struct work_struct *work)
{
- if (!maple_dma_done())
- return;
if (!list_empty(&maple_sentq))
return;
+ if (!maple_dma_done())
+ return;
ctrl_outl(0, MAPLE_ENABLE);
- liststatus = 0;
bus_for_each_dev(&maple_bus_type, NULL, NULL,
setup_maple_commands);
if (time_after(jiffies, maple_pnp_time))
maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL;
- if (liststatus && list_empty(&maple_sentq)) {
+ mutex_lock(&maple_wlist_lock);
+ if (!list_empty(&maple_waitq) && list_empty(&maple_sentq)) {
+ mutex_unlock(&maple_wlist_lock);
+ mutex_lock(&maple_list_lock);
INIT_LIST_HEAD(&maple_sentq);
+ mutex_unlock(&maple_list_lock);
maple_send();
+ } else {
+ mutex_unlock(&maple_wlist_lock);
}
+
maplebus_dma_reset();
}
/* handle devices added via hotplugs - placing them on queue for DEVINFO*/
static void maple_map_subunits(struct maple_device *mdev, int submask)
{
- int retval, k, devcheck;
+ int retval, k, devcheck, locking;
struct maple_device *mdev_add;
struct maple_device_specify ds;
+ ds.port = mdev->port;
for (k = 0; k < 5; k++) {
- ds.port = mdev->port;
ds.unit = k + 1;
retval bus_for_each_dev(&maple_bus_type, NULL, &ds,
@@ -437,9 +448,15 @@ static void maple_map_subunits(struct maple_device *mdev, int submask)
mdev_add = maple_alloc_dev(mdev->port, k + 1);
if (!mdev_add)
return;
+ locking = down_trylock(&mdev_add->mq->sem);
+ if (locking) {
+ up(&mdev_add->mq->sem);
+ down_interruptible(&mdev_add->mq->sem);
+ }
mdev_add->mq->command = MAPLE_COMMAND_DEVINFO;
mdev_add->mq->length = 0;
maple_add_packet(mdev_add->mq);
+ /* mark that we are checking sub devices */
scanning = 1;
}
submask = submask >> 1;
@@ -512,15 +529,17 @@ static void maple_dma_handler(struct work_struct *work)
struct maple_device *dev;
char *recvbuf;
enum maple_code code;
- int i;
+ int i, locking;
if (!maple_dma_done())
return;
ctrl_outl(0, MAPLE_ENABLE);
+ mutex_lock(&maple_list_lock);
if (!list_empty(&maple_sentq)) {
list_for_each_entry_safe(mq, nmq, &maple_sentq, list) {
recvbuf = mq->recvbuf;
code = recvbuf[0];
+ up(&mq->sem);
dev = mq->dev;
switch (code) {
case MAPLE_RESPONSE_NONE:
@@ -559,18 +578,26 @@ static void maple_dma_handler(struct work_struct *work)
}
}
INIT_LIST_HEAD(&maple_sentq);
+ mutex_unlock(&maple_list_lock);
+ /* if scanning is 1 then we have subdevices to check */
if (scanning = 1) {
maple_send();
scanning = 2;
} else
scanning = 0;
-
+ /*check if we have actually tested all ports yet */
if (!fullscan) {
fullscan = 1;
for (i = 0; i < MAPLE_PORTS; i++) {
if (checked[i] = false) {
fullscan = 0;
dev = baseunits[i];
+ locking = down_trylock(&dev->mq->sem);
+ if (locking) {
+ up(&dev->mq->sem);
+ down_interruptible
+ (&dev->mq->sem);
+ }
dev->mq->command MAPLE_COMMAND_DEVINFO;
dev->mq->length = 0;
@@ -578,8 +605,11 @@ static void maple_dma_handler(struct work_struct *work)
}
}
}
+ /* mark that we have been through the first scan */
if (started = 0)
started = 1;
+ } else {
+ mutex_unlock(&maple_list_lock);
}
maplebus_dma_reset();
}
@@ -631,7 +661,7 @@ static int match_maple_bus_driver(struct device *devptr,
if (maple_dev->devinfo.function = 0xFFFFFFFF)
return 0;
else if (maple_dev->devinfo.function &
- be32_to_cpu(maple_drv->function))
+ cpu_to_be32(maple_drv->function))
return 1;
return 0;
}
@@ -713,6 +743,8 @@ static int __init maple_bus_init(void)
if (!maple_queue_cache)
goto cleanup_bothirqs;
+ INIT_LIST_HEAD(&maple_waitq);
+
/* setup maple ports */
for (i = 0; i < MAPLE_PORTS; i++) {
checked[i] = false;
@@ -723,6 +755,7 @@ static int __init maple_bus_init(void)
maple_free_dev(mdev[i]);
goto cleanup_cache;
}
+ down_interruptible(&mdev[i]->mq->sem);
mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO;
mdev[i]->mq->length = 0;
maple_add_packet(mdev[i]->mq);
diff --git a/include/linux/maple.h b/include/linux/maple.h
index d31e36e..e40142e 100644
--- a/include/linux/maple.h
+++ b/include/linux/maple.h
@@ -33,6 +33,7 @@ struct mapleq {
void *sendbuf, *recvbuf, *recvbufdcsp;
unsigned char length;
enum maple_code command;
+ struct semaphore sem;
};
struct maple_devinfo {
@@ -73,6 +74,7 @@ void maple_getcond_callback(struct maple_device *dev,
int maple_driver_register(struct device_driver *drv);
void maple_add_packet(struct mapleq *mq);
+
#define to_maple_dev(n) container_of(n, struct maple_device, dev)
#define to_maple_driver(n) container_of(n, struct maple_driver, drv)
WARNING: multiple messages have this Message-ID (diff)
From: Adrian McMenamin <adrian@newgolddream.dyndns.info>
To: dwmw2@infradead.org, Greg KH <greg@kroah.com>,
Paul Mundt <lethal@linux-sh.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
linux-sh <linux-sh@vger.kernel.org>,
linux-mtd@vger.kernel.org
Subject: [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device
Date: Tue, 18 Mar 2008 22:49:14 +0000 [thread overview]
Message-ID: <1205880554.6250.25.camel@localhost.localdomain> (raw)
In-Reply-To: <1205879413.6250.13.camel@localhost.localdomain>
These patches update the maple bus driver with a semaphore to allow
other maple drivers to inject arbitrary packets (eg block reads and
writes) into the maple bus packet stream - so allowing support for the
VMU (and, eventually, other maple devices).
The patches also ensure that the maple bus driver properly supports the
device model through probing.
Signed-off-by: Adrian McMenamin <adrian@mcmen.demon.co.uk>
---
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index 617efb1..57a118a 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -47,13 +47,14 @@ static LIST_HEAD(maple_waitq);
static LIST_HEAD(maple_sentq);
static DEFINE_MUTEX(maple_list_lock);
+static DEFINE_MUTEX(maple_wlist_lock);
static struct maple_driver maple_dummy_driver;
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, fullscan;
+static int started, scanning, fullscan;
static struct kmem_cache *maple_queue_cache;
struct maple_device_specify {
@@ -135,9 +136,9 @@ static void maple_release_device(struct device *dev)
*/
void maple_add_packet(struct mapleq *mq)
{
- mutex_lock(&maple_list_lock);
+ mutex_lock(&maple_wlist_lock);
list_add(&mq->list, &maple_waitq);
- mutex_unlock(&maple_list_lock);
+ mutex_unlock(&maple_wlist_lock);
}
EXPORT_SYMBOL_GPL(maple_add_packet);
@@ -147,17 +148,21 @@ static struct mapleq *maple_allocq(struct maple_device *mdev)
mq = kmalloc(sizeof(*mq), GFP_KERNEL);
if (!mq)
- return NULL;
+ goto failed_nomem;
mq->dev = mdev;
mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL);
mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp);
- if (!mq->recvbuf) {
- kfree(mq);
- return NULL;
- }
+ if (!mq->recvbuf)
+ goto failed_p2;
+ init_MUTEX(&mq->sem);
return mq;
+
+failed_p2:
+ kfree(mq);
+failed_nomem:
+ return NULL;
}
static struct maple_device *maple_alloc_dev(int port, int unit)
@@ -178,7 +183,6 @@ static struct maple_device *maple_alloc_dev(int port, int unit)
}
mdev->dev.bus = &maple_bus_type;
mdev->dev.parent = &maple_bus;
- mdev->function = 0;
return mdev;
}
@@ -216,8 +220,7 @@ static void maple_build_block(struct mapleq *mq)
*maple_sendptr++ = PHYSADDR(mq->recvbuf);
*maple_sendptr++ =
mq->command | (to << 8) | (from << 16) | (len << 24);
-
- while (len-- > 0)
+ while (len-- > 0)
*maple_sendptr++ = *lsendbuf++;
}
@@ -230,16 +233,24 @@ static void maple_send(void)
if (!list_empty(&maple_sentq))
return;
- if (list_empty(&maple_waitq) || !maple_dma_done())
+ mutex_lock(&maple_wlist_lock);
+ if (list_empty(&maple_waitq) || !maple_dma_done()) {
+ mutex_unlock(&maple_wlist_lock);
return;
+ }
+ mutex_unlock(&maple_wlist_lock);
maple_packets = 0;
maple_sendptr = maple_lastptr = maple_sendbuf;
- list_for_each_entry_safe(mq, nmq, &maple_waitq, list) {
+ mutex_lock(&maple_list_lock);
+ mutex_lock(&maple_wlist_lock);
+ list_for_each_entry_safe(mq, nmq, &maple_waitq, list) {
maple_build_block(mq);
list_move(&mq->list, &maple_sentq);
- if (maple_packets++ > MAPLE_MAXPACKETS)
+ if (maple_packets++ > MAPLE_MAXPACKETS)
break;
}
+ mutex_unlock(&maple_wlist_lock);
+ mutex_unlock(&maple_list_lock);
if (maple_packets > 0) {
for (i = 0; i < (1 << MAPLE_DMA_PAGES); i++)
dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE,
@@ -247,7 +258,8 @@ static void maple_send(void)
}
}
-static int attach_matching_maple_driver(struct device_driver *driver,
+/* check if there is a driver registered likely to match this device */
+static int check_matching_maple_driver(struct device_driver *driver,
void *devptr)
{
struct maple_driver *maple_drv;
@@ -255,12 +267,8 @@ static int attach_matching_maple_driver(struct device_driver *driver,
mdev = devptr;
maple_drv = to_maple_driver(driver);
- if (mdev->devinfo.function & be32_to_cpu(maple_drv->function)) {
- if (maple_drv->connect(mdev) == 0) {
- mdev->driver = maple_drv;
- return 1;
- }
- }
+ if (mdev->devinfo.function & cpu_to_be32(maple_drv->function))
+ return 1;
return 0;
}
@@ -268,11 +276,6 @@ static void maple_detach_driver(struct maple_device *mdev)
{
if (!mdev)
return;
- if (mdev->driver) {
- if (mdev->driver->disconnect)
- mdev->driver->disconnect(mdev);
- }
- mdev->driver = NULL;
device_unregister(&mdev->dev);
mdev = NULL;
}
@@ -328,8 +331,8 @@ static void maple_attach_driver(struct maple_device *mdev)
mdev->port, mdev->unit, function);
matched =
- bus_for_each_drv(&maple_bus_type, NULL, mdev,
- attach_matching_maple_driver);
+ bus_for_each_drv(&maple_bus_type, NULL, mdev,
+ check_matching_maple_driver);
if (matched == 0) {
/* Driver does not exist yet */
@@ -342,7 +345,7 @@ static void maple_attach_driver(struct maple_device *mdev)
}
mdev->function = function;
mdev->dev.release = &maple_release_device;
- retval = device_register(&mdev->dev);
+ retval = device_register(&mdev->dev);
if (retval) {
printk(KERN_INFO
"Maple bus: Attempt to register device"
@@ -377,18 +380,20 @@ static int setup_maple_commands(struct device *device, void *ignored)
if ((maple_dev->interval > 0)
&& time_after(jiffies, maple_dev->when)) {
+ if (down_trylock(&maple_dev->mq->sem))
+ return 0;
maple_dev->when = jiffies + maple_dev->interval;
maple_dev->mq->command = MAPLE_COMMAND_GETCOND;
maple_dev->mq->sendbuf = &maple_dev->function;
maple_dev->mq->length = 1;
maple_add_packet(maple_dev->mq);
- liststatus++;
} else {
if (time_after(jiffies, maple_pnp_time)) {
+ if (down_trylock(&maple_dev->mq->sem))
+ return -1;
maple_dev->mq->command = MAPLE_COMMAND_DEVINFO;
maple_dev->mq->length = 0;
maple_add_packet(maple_dev->mq);
- liststatus++;
}
}
@@ -398,32 +403,38 @@ static int setup_maple_commands(struct device *device, void *ignored)
/* VBLANK bottom half - implemented via workqueue */
static void maple_vblank_handler(struct work_struct *work)
{
- if (!maple_dma_done())
- return;
if (!list_empty(&maple_sentq))
return;
+ if (!maple_dma_done())
+ return;
ctrl_outl(0, MAPLE_ENABLE);
- liststatus = 0;
bus_for_each_dev(&maple_bus_type, NULL, NULL,
setup_maple_commands);
if (time_after(jiffies, maple_pnp_time))
maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL;
- if (liststatus && list_empty(&maple_sentq)) {
+ mutex_lock(&maple_wlist_lock);
+ if (!list_empty(&maple_waitq) && list_empty(&maple_sentq)) {
+ mutex_unlock(&maple_wlist_lock);
+ mutex_lock(&maple_list_lock);
INIT_LIST_HEAD(&maple_sentq);
+ mutex_unlock(&maple_list_lock);
maple_send();
+ } else {
+ mutex_unlock(&maple_wlist_lock);
}
+
maplebus_dma_reset();
}
/* handle devices added via hotplugs - placing them on queue for DEVINFO*/
static void maple_map_subunits(struct maple_device *mdev, int submask)
{
- int retval, k, devcheck;
+ int retval, k, devcheck, locking;
struct maple_device *mdev_add;
struct maple_device_specify ds;
+ ds.port = mdev->port;
for (k = 0; k < 5; k++) {
- ds.port = mdev->port;
ds.unit = k + 1;
retval =
bus_for_each_dev(&maple_bus_type, NULL, &ds,
@@ -437,9 +448,15 @@ static void maple_map_subunits(struct maple_device *mdev, int submask)
mdev_add = maple_alloc_dev(mdev->port, k + 1);
if (!mdev_add)
return;
+ locking = down_trylock(&mdev_add->mq->sem);
+ if (locking) {
+ up(&mdev_add->mq->sem);
+ down_interruptible(&mdev_add->mq->sem);
+ }
mdev_add->mq->command = MAPLE_COMMAND_DEVINFO;
mdev_add->mq->length = 0;
maple_add_packet(mdev_add->mq);
+ /* mark that we are checking sub devices */
scanning = 1;
}
submask = submask >> 1;
@@ -512,15 +529,17 @@ static void maple_dma_handler(struct work_struct *work)
struct maple_device *dev;
char *recvbuf;
enum maple_code code;
- int i;
+ int i, locking;
if (!maple_dma_done())
return;
ctrl_outl(0, MAPLE_ENABLE);
+ mutex_lock(&maple_list_lock);
if (!list_empty(&maple_sentq)) {
list_for_each_entry_safe(mq, nmq, &maple_sentq, list) {
recvbuf = mq->recvbuf;
code = recvbuf[0];
+ up(&mq->sem);
dev = mq->dev;
switch (code) {
case MAPLE_RESPONSE_NONE:
@@ -559,18 +578,26 @@ static void maple_dma_handler(struct work_struct *work)
}
}
INIT_LIST_HEAD(&maple_sentq);
+ mutex_unlock(&maple_list_lock);
+ /* if scanning is 1 then we have subdevices to check */
if (scanning == 1) {
maple_send();
scanning = 2;
} else
scanning = 0;
-
+ /*check if we have actually tested all ports yet */
if (!fullscan) {
fullscan = 1;
for (i = 0; i < MAPLE_PORTS; i++) {
if (checked[i] == false) {
fullscan = 0;
dev = baseunits[i];
+ locking = down_trylock(&dev->mq->sem);
+ if (locking) {
+ up(&dev->mq->sem);
+ down_interruptible
+ (&dev->mq->sem);
+ }
dev->mq->command =
MAPLE_COMMAND_DEVINFO;
dev->mq->length = 0;
@@ -578,8 +605,11 @@ static void maple_dma_handler(struct work_struct *work)
}
}
}
+ /* mark that we have been through the first scan */
if (started == 0)
started = 1;
+ } else {
+ mutex_unlock(&maple_list_lock);
}
maplebus_dma_reset();
}
@@ -631,7 +661,7 @@ static int match_maple_bus_driver(struct device *devptr,
if (maple_dev->devinfo.function == 0xFFFFFFFF)
return 0;
else if (maple_dev->devinfo.function &
- be32_to_cpu(maple_drv->function))
+ cpu_to_be32(maple_drv->function))
return 1;
return 0;
}
@@ -713,6 +743,8 @@ static int __init maple_bus_init(void)
if (!maple_queue_cache)
goto cleanup_bothirqs;
+ INIT_LIST_HEAD(&maple_waitq);
+
/* setup maple ports */
for (i = 0; i < MAPLE_PORTS; i++) {
checked[i] = false;
@@ -723,6 +755,7 @@ static int __init maple_bus_init(void)
maple_free_dev(mdev[i]);
goto cleanup_cache;
}
+ down_interruptible(&mdev[i]->mq->sem);
mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO;
mdev[i]->mq->length = 0;
maple_add_packet(mdev[i]->mq);
diff --git a/include/linux/maple.h b/include/linux/maple.h
index d31e36e..e40142e 100644
--- a/include/linux/maple.h
+++ b/include/linux/maple.h
@@ -33,6 +33,7 @@ struct mapleq {
void *sendbuf, *recvbuf, *recvbufdcsp;
unsigned char length;
enum maple_code command;
+ struct semaphore sem;
};
struct maple_devinfo {
@@ -73,6 +74,7 @@ void maple_getcond_callback(struct maple_device *dev,
int maple_driver_register(struct device_driver *drv);
void maple_add_packet(struct mapleq *mq);
+
#define to_maple_dev(n) container_of(n, struct maple_device, dev)
#define to_maple_driver(n) container_of(n, struct maple_driver, drv)
next prev parent reply other threads:[~2008-03-18 22:49 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-18 22:30 [PATCH] 0/2 Add support for maple "Visual Memory Unit" on SEGA Adrian McMenamin
2008-03-18 22:30 ` [PATCH] 0/2 Add support for maple "Visual Memory Unit" on SEGA Dreamcast Adrian McMenamin
2008-03-18 22:49 ` Adrian McMenamin [this message]
2008-03-18 22:49 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device Adrian McMenamin
2008-03-18 22:56 ` [PATCH] 2/2 mtd: Add support for the Dreamcast VMU flash Adrian McMenamin
2008-03-18 22:56 ` Adrian McMenamin
2008-03-20 21:10 ` Andrew Morton
2008-03-20 21:10 ` Andrew Morton
2008-03-20 22:34 ` Adrian McMenamin
2008-03-20 22:34 ` Adrian McMenamin
2008-03-20 20:56 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU Andrew Morton
2008-03-20 20:56 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device Andrew Morton
2008-03-20 22:23 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU Adrian McMenamin
2008-03-20 22:23 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device Adrian McMenamin
2008-03-20 22:39 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU Andrew Morton
2008-03-20 22:39 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device Andrew Morton
2008-03-20 22:52 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU Adrian McMenamin
2008-03-20 22:52 ` [PATCH] 1/2 Maple: Update bus driver to allow support of VMU device Adrian McMenamin
2008-03-21 5:11 ` Paul Mundt
2008-03-21 5:11 ` Paul Mundt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1205880554.6250.25.camel@localhost.localdomain \
--to=adrian@newgolddream.dyndns.info \
--cc=dwmw2@infradead.org \
--cc=greg@kroah.com \
--cc=lethal@linux-sh.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@vger.kernel.org \
--cc=linux-sh@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.