Commit 400822fe authored by Martyn Welch's avatar Martyn Welch Committed by Greg Kroah-Hartman

Staging: Use proper mutexes in the tsi-148 VME driver

The VME core and tsi-148 driver currently use semaphores as mutexes. Switch to proper
mutex implementation.
Signed-off-by: default avatarMartyn Welch <martyn.welch@gefanuc.com>
Reviewed-by: default avatarEmilio G. Cota <cota@braap.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 238add52
...@@ -76,13 +76,13 @@ void (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */ ...@@ -76,13 +76,13 @@ void (*lm_callback[4])(int); /* Called in interrupt handler, be careful! */
void *crcsr_kernel; void *crcsr_kernel;
dma_addr_t crcsr_bus; dma_addr_t crcsr_bus;
struct vme_master_resource *flush_image; struct vme_master_resource *flush_image;
struct semaphore vme_rmw; /* Only one RMW cycle at a time */ struct mutex vme_rmw; /* Only one RMW cycle at a time */
struct semaphore vme_int; /* struct mutex vme_int; /*
* Only one VME interrupt can be * Only one VME interrupt can be
* generated at a time, provide locking * generated at a time, provide locking
*/ */
struct semaphore vme_irq; /* Locking for VME irq callback configuration */ struct mutex vme_irq; /* Locking for VME irq callback configuration */
struct semaphore vme_lm; /* Locking for location monitor operations */ struct mutex vme_lm; /* Locking for location monitor operations */
static char driver_name[] = "vme_tsi148"; static char driver_name[] = "vme_tsi148";
...@@ -445,11 +445,10 @@ int tsi148_request_irq(int level, int statid, ...@@ -445,11 +445,10 @@ int tsi148_request_irq(int level, int statid,
{ {
u32 tmp; u32 tmp;
/* Get semaphore */ mutex_lock(&(vme_irq));
down(&(vme_irq));
if(tsi148_bridge->irq[level - 1].callback[statid].func) { if(tsi148_bridge->irq[level - 1].callback[statid].func) {
up(&(vme_irq)); mutex_unlock(&(vme_irq));
printk("VME Interrupt already taken\n"); printk("VME Interrupt already taken\n");
return -EBUSY; return -EBUSY;
} }
...@@ -468,8 +467,7 @@ int tsi148_request_irq(int level, int statid, ...@@ -468,8 +467,7 @@ int tsi148_request_irq(int level, int statid,
tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1]; tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN); iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
/* Release semaphore */ mutex_unlock(&(vme_irq));
up(&(vme_irq));
return 0; return 0;
} }
...@@ -482,8 +480,7 @@ void tsi148_free_irq(int level, int statid) ...@@ -482,8 +480,7 @@ void tsi148_free_irq(int level, int statid)
u32 tmp; u32 tmp;
struct pci_dev *pdev; struct pci_dev *pdev;
/* Get semaphore */ mutex_lock(&(vme_irq));
down(&(vme_irq));
tsi148_bridge->irq[level - 1].count--; tsi148_bridge->irq[level - 1].count--;
...@@ -505,22 +502,18 @@ void tsi148_free_irq(int level, int statid) ...@@ -505,22 +502,18 @@ void tsi148_free_irq(int level, int statid)
tsi148_bridge->irq[level - 1].callback[statid].func = NULL; tsi148_bridge->irq[level - 1].callback[statid].func = NULL;
tsi148_bridge->irq[level - 1].callback[statid].priv_data = NULL; tsi148_bridge->irq[level - 1].callback[statid].priv_data = NULL;
/* Release semaphore */ mutex_unlock(&(vme_irq));
up(&(vme_irq));
} }
/* /*
* Generate a VME bus interrupt at the requested level & vector. Wait for * Generate a VME bus interrupt at the requested level & vector. Wait for
* interrupt to be acked. * interrupt to be acked.
*
* Only one interrupt can be generated at a time - so add a semaphore.
*/ */
int tsi148_generate_irq(int level, int statid) int tsi148_generate_irq(int level, int statid)
{ {
u32 tmp; u32 tmp;
/* Get semaphore */ mutex_lock(&(vme_int));
down(&(vme_int));
/* Read VICR register */ /* Read VICR register */
tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR); tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR);
...@@ -537,8 +530,7 @@ int tsi148_generate_irq(int level, int statid) ...@@ -537,8 +530,7 @@ int tsi148_generate_irq(int level, int statid)
/* XXX Consider implementing a timeout? */ /* XXX Consider implementing a timeout? */
wait_event_interruptible(iack_queue, tsi148_iack_received()); wait_event_interruptible(iack_queue, tsi148_iack_received());
/* Release semaphore */ mutex_unlock(&(vme_int));
up(&(vme_int));
return 0; return 0;
} }
...@@ -1379,7 +1371,7 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, ...@@ -1379,7 +1371,7 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
} }
/* XXX We need to change vme_master_resource->sem to a spinlock so that read /* XXX We need to change vme_master_resource->mtx to a spinlock so that read
* and write functions can be used in an interrupt context * and write functions can be used in an interrupt context
*/ */
ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
...@@ -1455,7 +1447,7 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image, ...@@ -1455,7 +1447,7 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image,
i = image->number; i = image->number;
/* Locking as we can only do one of these at a time */ /* Locking as we can only do one of these at a time */
down(&(vme_rmw)); mutex_lock(&(vme_rmw));
/* Lock image */ /* Lock image */
spin_lock(&(image->lock)); spin_lock(&(image->lock));
...@@ -1490,7 +1482,7 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image, ...@@ -1490,7 +1482,7 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image,
spin_unlock(&(image->lock)); spin_unlock(&(image->lock));
up(&(vme_rmw)); mutex_unlock(&(vme_rmw));
return result; return result;
} }
...@@ -1867,7 +1859,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) ...@@ -1867,7 +1859,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
ctrlr = list->parent; ctrlr = list->parent;
down(&(ctrlr->sem)); mutex_lock(&(ctrlr->mtx));
channel = ctrlr->number; channel = ctrlr->number;
...@@ -1878,7 +1870,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) ...@@ -1878,7 +1870,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
* Return busy. * Return busy.
*/ */
/* Need to add to pending here */ /* Need to add to pending here */
up(&(ctrlr->sem)); mutex_unlock(&(ctrlr->mtx));
return -EBUSY; return -EBUSY;
} else { } else {
list_add(&(list->list), &(ctrlr->running)); list_add(&(list->list), &(ctrlr->running));
...@@ -1932,7 +1924,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) ...@@ -1932,7 +1924,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
bus_addr = virt_to_bus(&(entry->descriptor)); bus_addr = virt_to_bus(&(entry->descriptor));
up(&(ctrlr->sem)); mutex_unlock(&(ctrlr->mtx));
reg_split(bus_addr, &bus_addr_high, &bus_addr_low); reg_split(bus_addr, &bus_addr_high, &bus_addr_low);
...@@ -1959,9 +1951,9 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) ...@@ -1959,9 +1951,9 @@ int tsi148_dma_list_exec(struct vme_dma_list *list)
} }
/* Remove list from running list */ /* Remove list from running list */
down(&(ctrlr->sem)); mutex_lock(&(ctrlr->mtx));
list_del(&(list->list)); list_del(&(list->list));
up(&(ctrlr->sem)); mutex_unlock(&(ctrlr->mtx));
return retval; return retval;
} }
...@@ -1999,13 +1991,12 @@ int tsi148_lm_set(unsigned long long lm_base, vme_address_t aspace, ...@@ -1999,13 +1991,12 @@ int tsi148_lm_set(unsigned long long lm_base, vme_address_t aspace,
u32 lm_base_high, lm_base_low, lm_ctl = 0; u32 lm_base_high, lm_base_low, lm_ctl = 0;
int i; int i;
/* Get semaphore */ mutex_lock(&(vme_lm));
down(&(vme_lm));
/* If we already have a callback attached, we can't move it! */ /* If we already have a callback attached, we can't move it! */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if(lm_callback[i] != NULL) { if(lm_callback[i] != NULL) {
up(&(vme_lm)); mutex_unlock(&(vme_lm));
printk("Location monitor callback attached, can't " printk("Location monitor callback attached, can't "
"reset\n"); "reset\n");
return -EBUSY; return -EBUSY;
...@@ -2026,7 +2017,7 @@ int tsi148_lm_set(unsigned long long lm_base, vme_address_t aspace, ...@@ -2026,7 +2017,7 @@ int tsi148_lm_set(unsigned long long lm_base, vme_address_t aspace,
lm_ctl |= TSI148_LCSR_LMAT_AS_A64; lm_ctl |= TSI148_LCSR_LMAT_AS_A64;
break; break;
default: default:
up(&(vme_lm)); mutex_unlock(&(vme_lm));
printk("Invalid address space\n"); printk("Invalid address space\n");
return -EINVAL; return -EINVAL;
break; break;
...@@ -2047,7 +2038,7 @@ int tsi148_lm_set(unsigned long long lm_base, vme_address_t aspace, ...@@ -2047,7 +2038,7 @@ int tsi148_lm_set(unsigned long long lm_base, vme_address_t aspace,
iowrite32be(lm_base_low, tsi148_bridge->base + TSI148_LCSR_LMBAL); iowrite32be(lm_base_low, tsi148_bridge->base + TSI148_LCSR_LMBAL);
iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT);
up(&(vme_lm)); mutex_unlock(&(vme_lm));
return 0; return 0;
} }
...@@ -2060,8 +2051,7 @@ int tsi148_lm_get(unsigned long long *lm_base, vme_address_t *aspace, ...@@ -2060,8 +2051,7 @@ int tsi148_lm_get(unsigned long long *lm_base, vme_address_t *aspace,
{ {
u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0; u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0;
/* Get semaphore */ mutex_lock(&(vme_lm));
down(&(vme_lm));
lm_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAU); lm_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAU);
lm_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAL); lm_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAL);
...@@ -2094,7 +2084,7 @@ int tsi148_lm_get(unsigned long long *lm_base, vme_address_t *aspace, ...@@ -2094,7 +2084,7 @@ int tsi148_lm_get(unsigned long long *lm_base, vme_address_t *aspace,
if (lm_ctl & TSI148_LCSR_LMAT_DATA) if (lm_ctl & TSI148_LCSR_LMAT_DATA)
*cycle |= VME_DATA; *cycle |= VME_DATA;
up(&(vme_lm)); mutex_unlock(&(vme_lm));
return enabled; return enabled;
} }
...@@ -2108,20 +2098,19 @@ int tsi148_lm_attach(int monitor, void (*callback)(int)) ...@@ -2108,20 +2098,19 @@ int tsi148_lm_attach(int monitor, void (*callback)(int))
{ {
u32 lm_ctl, tmp; u32 lm_ctl, tmp;
/* Get semaphore */ mutex_lock(&(vme_lm));
down(&(vme_lm));
/* Ensure that the location monitor is configured - need PGM or DATA */ /* Ensure that the location monitor is configured - need PGM or DATA */
lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT); lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) {
up(&(vme_lm)); mutex_unlock(&(vme_lm));
printk("Location monitor not properly configured\n"); printk("Location monitor not properly configured\n");
return -EINVAL; return -EINVAL;
} }
/* Check that a callback isn't already attached */ /* Check that a callback isn't already attached */
if (lm_callback[monitor] != NULL) { if (lm_callback[monitor] != NULL) {
up(&(vme_lm)); mutex_unlock(&(vme_lm));
printk("Existing callback attached\n"); printk("Existing callback attached\n");
return -EBUSY; return -EBUSY;
} }
...@@ -2144,7 +2133,7 @@ int tsi148_lm_attach(int monitor, void (*callback)(int)) ...@@ -2144,7 +2133,7 @@ int tsi148_lm_attach(int monitor, void (*callback)(int))
iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT); iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT);
} }
up(&(vme_lm)); mutex_unlock(&(vme_lm));
return 0; return 0;
} }
...@@ -2156,8 +2145,7 @@ int tsi148_lm_detach(int monitor) ...@@ -2156,8 +2145,7 @@ int tsi148_lm_detach(int monitor)
{ {
u32 lm_en, tmp; u32 lm_en, tmp;
/* Get semaphore */ mutex_lock(&(vme_lm));
down(&(vme_lm));
/* Disable Location Monitor and ensure previous interrupts are clear */ /* Disable Location Monitor and ensure previous interrupts are clear */
lm_en = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN); lm_en = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
...@@ -2182,7 +2170,7 @@ int tsi148_lm_detach(int monitor) ...@@ -2182,7 +2170,7 @@ int tsi148_lm_detach(int monitor)
iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_LMAT); iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_LMAT);
} }
up(&(vme_lm)); mutex_unlock(&(vme_lm));
return 0; return 0;
} }
...@@ -2347,10 +2335,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2347,10 +2335,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
init_waitqueue_head(&dma_queue[0]); init_waitqueue_head(&dma_queue[0]);
init_waitqueue_head(&dma_queue[1]); init_waitqueue_head(&dma_queue[1]);
init_waitqueue_head(&iack_queue); init_waitqueue_head(&iack_queue);
init_MUTEX(&(vme_int)); mutex_init(&(vme_int));
init_MUTEX(&(vme_irq)); mutex_init(&(vme_irq));
init_MUTEX(&(vme_rmw)); mutex_init(&(vme_rmw));
init_MUTEX(&(vme_lm)); mutex_init(&(vme_lm));
tsi148_bridge->parent = &(pdev->dev); tsi148_bridge->parent = &(pdev->dev);
strcpy(tsi148_bridge->name, driver_name); strcpy(tsi148_bridge->name, driver_name);
...@@ -2436,7 +2424,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2436,7 +2424,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_slave; goto err_slave;
} }
slave_image->parent = tsi148_bridge; slave_image->parent = tsi148_bridge;
init_MUTEX(&(slave_image->sem)); mutex_init(&(slave_image->mtx));
slave_image->locked = 0; slave_image->locked = 0;
slave_image->number = i; slave_image->number = i;
slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 | slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
...@@ -2462,7 +2450,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2462,7 +2450,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_dma; goto err_dma;
} }
dma_ctrlr->parent = tsi148_bridge; dma_ctrlr->parent = tsi148_bridge;
init_MUTEX(&(dma_ctrlr->sem)); mutex_init(&(dma_ctrlr->mtx));
dma_ctrlr->locked = 0; dma_ctrlr->locked = 0;
dma_ctrlr->number = i; dma_ctrlr->number = i;
INIT_LIST_HEAD(&(dma_ctrlr->pending)); INIT_LIST_HEAD(&(dma_ctrlr->pending));
......
...@@ -28,15 +28,15 @@ ...@@ -28,15 +28,15 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/semaphore.h> #include <linux/mutex.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include "vme.h" #include "vme.h"
#include "vme_bridge.h" #include "vme_bridge.h"
/* Bitmask and semaphore to keep track of bridge numbers */ /* Bitmask and mutex to keep track of bridge numbers */
static unsigned int vme_bus_numbers; static unsigned int vme_bus_numbers;
DECLARE_MUTEX(vme_bus_num_sem); DEFINE_MUTEX(vme_bus_num_mtx);
static void __exit vme_exit (void); static void __exit vme_exit (void);
static int __init vme_init (void); static int __init vme_init (void);
...@@ -251,17 +251,17 @@ struct vme_resource * vme_slave_request(struct device *dev, ...@@ -251,17 +251,17 @@ struct vme_resource * vme_slave_request(struct device *dev,
} }
/* Find an unlocked and compatible image */ /* Find an unlocked and compatible image */
down(&(slave_image->sem)); mutex_lock(&(slave_image->mtx));
if(((slave_image->address_attr & address) == address) && if(((slave_image->address_attr & address) == address) &&
((slave_image->cycle_attr & cycle) == cycle) && ((slave_image->cycle_attr & cycle) == cycle) &&
(slave_image->locked == 0)) { (slave_image->locked == 0)) {
slave_image->locked = 1; slave_image->locked = 1;
up(&(slave_image->sem)); mutex_unlock(&(slave_image->mtx));
allocated_image = slave_image; allocated_image = slave_image;
break; break;
} }
up(&(slave_image->sem)); mutex_unlock(&(slave_image->mtx));
} }
/* No free image */ /* No free image */
...@@ -280,9 +280,9 @@ struct vme_resource * vme_slave_request(struct device *dev, ...@@ -280,9 +280,9 @@ struct vme_resource * vme_slave_request(struct device *dev,
err_alloc: err_alloc:
/* Unlock image */ /* Unlock image */
down(&(slave_image->sem)); mutex_lock(&(slave_image->mtx));
slave_image->locked = 0; slave_image->locked = 0;
up(&(slave_image->sem)); mutex_unlock(&(slave_image->mtx));
err_image: err_image:
err_bus: err_bus:
return NULL; return NULL;
...@@ -365,12 +365,12 @@ void vme_slave_free(struct vme_resource *resource) ...@@ -365,12 +365,12 @@ void vme_slave_free(struct vme_resource *resource)
} }
/* Unlock image */ /* Unlock image */
down(&(slave_image->sem)); mutex_lock(&(slave_image->mtx));
if (slave_image->locked == 0) if (slave_image->locked == 0)
printk(KERN_ERR "Image is already free\n"); printk(KERN_ERR "Image is already free\n");
slave_image->locked = 0; slave_image->locked = 0;
up(&(slave_image->sem)); mutex_unlock(&(slave_image->mtx));
/* Free up resource memory */ /* Free up resource memory */
kfree(resource); kfree(resource);
...@@ -668,14 +668,14 @@ struct vme_resource *vme_request_dma(struct device *dev) ...@@ -668,14 +668,14 @@ struct vme_resource *vme_request_dma(struct device *dev)
} }
/* Find an unlocked controller */ /* Find an unlocked controller */
down(&(dma_ctrlr->sem)); mutex_lock(&(dma_ctrlr->mtx));
if(dma_ctrlr->locked == 0) { if(dma_ctrlr->locked == 0) {
dma_ctrlr->locked = 1; dma_ctrlr->locked = 1;
up(&(dma_ctrlr->sem)); mutex_unlock(&(dma_ctrlr->mtx));
allocated_ctrlr = dma_ctrlr; allocated_ctrlr = dma_ctrlr;
break; break;
} }
up(&(dma_ctrlr->sem)); mutex_unlock(&(dma_ctrlr->mtx));
} }
/* Check to see if we found a resource */ /* Check to see if we found a resource */
...@@ -694,9 +694,9 @@ struct vme_resource *vme_request_dma(struct device *dev) ...@@ -694,9 +694,9 @@ struct vme_resource *vme_request_dma(struct device *dev)
err_alloc: err_alloc:
/* Unlock image */ /* Unlock image */
down(&(dma_ctrlr->sem)); mutex_lock(&(dma_ctrlr->mtx));
dma_ctrlr->locked = 0; dma_ctrlr->locked = 0;
up(&(dma_ctrlr->sem)); mutex_unlock(&(dma_ctrlr->mtx));
err_ctrlr: err_ctrlr:
err_bus: err_bus:
return NULL; return NULL;
...@@ -726,7 +726,7 @@ struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource) ...@@ -726,7 +726,7 @@ struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
} }
INIT_LIST_HEAD(&(dma_list->entries)); INIT_LIST_HEAD(&(dma_list->entries));
dma_list->parent = ctrlr; dma_list->parent = ctrlr;
init_MUTEX(&(dma_list->sem)); mutex_init(&(dma_list->mtx));
return dma_list; return dma_list;
} }
...@@ -876,14 +876,14 @@ int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, ...@@ -876,14 +876,14 @@ int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
return -EINVAL; return -EINVAL;
} }
if (down_trylock(&(list->sem))) { if (mutex_trylock(&(list->mtx))) {
printk("Link List already submitted\n"); printk("Link List already submitted\n");
return -EINVAL; return -EINVAL;
} }
retval = bridge->dma_list_add(list, src, dest, count); retval = bridge->dma_list_add(list, src, dest, count);
up(&(list->sem)); mutex_unlock(&(list->mtx));
return retval; return retval;
} }
...@@ -899,11 +899,11 @@ int vme_dma_list_exec(struct vme_dma_list *list) ...@@ -899,11 +899,11 @@ int vme_dma_list_exec(struct vme_dma_list *list)
return -EINVAL; return -EINVAL;
} }
down(&(list->sem)); mutex_lock(&(list->mtx));
retval = bridge->dma_list_exec(list); retval = bridge->dma_list_exec(list);
up(&(list->sem)); mutex_unlock(&(list->mtx));
return retval; return retval;
} }
...@@ -919,7 +919,7 @@ int vme_dma_list_free(struct vme_dma_list *list) ...@@ -919,7 +919,7 @@ int vme_dma_list_free(struct vme_dma_list *list)
return -EINVAL; return -EINVAL;
} }
if (down_trylock(&(list->sem))) { if (mutex_trylock(&(list->mtx))) {
printk("Link List in use\n"); printk("Link List in use\n");
return -EINVAL; return -EINVAL;
} }
...@@ -931,10 +931,10 @@ int vme_dma_list_free(struct vme_dma_list *list) ...@@ -931,10 +931,10 @@ int vme_dma_list_free(struct vme_dma_list *list)
retval = bridge->dma_list_empty(list); retval = bridge->dma_list_empty(list);
if (retval) { if (retval) {
printk("Unable to empty link-list entries\n"); printk("Unable to empty link-list entries\n");
up(&(list->sem)); mutex_unlock(&(list->mtx));
return retval; return retval;
} }
up(&(list->sem)); mutex_unlock(&(list->mtx));
kfree(list); kfree(list);
return retval; return retval;
...@@ -952,20 +952,20 @@ int vme_dma_free(struct vme_resource *resource) ...@@ -952,20 +952,20 @@ int vme_dma_free(struct vme_resource *resource)
ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
if (down_trylock(&(ctrlr->sem))) { if (mutex_trylock(&(ctrlr->mtx))) {
printk("Resource busy, can't free\n"); printk("Resource busy, can't free\n");
return -EBUSY; return -EBUSY;
} }
if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) { if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) {
printk("Resource still processing transfers\n"); printk("Resource still processing transfers\n");
up(&(ctrlr->sem)); mutex_unlock(&(ctrlr->mtx));
return -EBUSY; return -EBUSY;
} }
ctrlr->locked = 0; ctrlr->locked = 0;
up(&(ctrlr->sem)); mutex_unlock(&(ctrlr->mtx));
return 0; return 0;
} }
...@@ -1149,23 +1149,23 @@ static int vme_alloc_bus_num(void) ...@@ -1149,23 +1149,23 @@ static int vme_alloc_bus_num(void)
{ {
int i; int i;
down(&vme_bus_num_sem); mutex_lock(&vme_bus_num_mtx);
for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) { for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) {
if (((vme_bus_numbers >> i) & 0x1) == 0) { if (((vme_bus_numbers >> i) & 0x1) == 0) {
vme_bus_numbers |= (0x1 << i); vme_bus_numbers |= (0x1 << i);
break; break;
} }
} }
up(&vme_bus_num_sem); mutex_unlock(&vme_bus_num_mtx);
return i; return i;
} }
static void vme_free_bus_num(int bus) static void vme_free_bus_num(int bus)
{ {
down(&vme_bus_num_sem); mutex_lock(&vme_bus_num_mtx);
vme_bus_numbers |= ~(0x1 << bus); vme_bus_numbers |= ~(0x1 << bus);
up(&vme_bus_num_sem); mutex_unlock(&vme_bus_num_mtx);
} }
int vme_register_bridge (struct vme_bridge *bridge) int vme_register_bridge (struct vme_bridge *bridge)
......
...@@ -11,7 +11,7 @@ struct vme_master_resource { ...@@ -11,7 +11,7 @@ struct vme_master_resource {
struct vme_bridge *parent; struct vme_bridge *parent;
/* /*
* We are likely to need to access the VME bus in interrupt context, so * We are likely to need to access the VME bus in interrupt context, so
* protect master routines with a spinlock rather than a semaphore. * protect master routines with a spinlock rather than a mutex.
*/ */
spinlock_t lock; spinlock_t lock;
int locked; int locked;
...@@ -26,7 +26,7 @@ struct vme_master_resource { ...@@ -26,7 +26,7 @@ struct vme_master_resource {
struct vme_slave_resource { struct vme_slave_resource {
struct list_head list; struct list_head list;
struct vme_bridge *parent; struct vme_bridge *parent;
struct semaphore sem; struct mutex mtx;
int locked; int locked;
int number; int number;
vme_address_t address_attr; vme_address_t address_attr;
...@@ -53,13 +53,13 @@ struct vme_dma_list { ...@@ -53,13 +53,13 @@ struct vme_dma_list {
struct list_head list; struct list_head list;
struct vme_dma_resource *parent; struct vme_dma_resource *parent;
struct list_head entries; struct list_head entries;
struct semaphore sem; struct mutex mtx;
}; };
struct vme_dma_resource { struct vme_dma_resource {
struct list_head list; struct list_head list;
struct vme_bridge *parent; struct vme_bridge *parent;
struct semaphore sem; struct mutex mtx;
int locked; int locked;
int number; int number;
struct list_head pending; struct list_head pending;
......
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