Commit 719b6399 authored by Ben Collins's avatar Ben Collins Committed by Linus Torvalds

[PATCH] 1394 updates

- New irq handler prototypes.
- Lots of un-enumurated locking fixes/cleanups (thanks in large part to
  spinlock debug compile options in the kernel).
- Other various trivial fixes.
parent 4f4b8e8c
......@@ -448,7 +448,7 @@ static int lock_regs(struct hpsb_host *host, int nodeid, quadlet_t *store,
/* bandwidth available algorithm adapted from IEEE 1394a-2000 spec */
if (arg > 0x1fff) {
*store = cpu_to_be32(old); /* change nothing */
break;
break;
}
data &= 0x1fff;
if (arg >= data) {
......
......@@ -455,6 +455,10 @@ struct video_card {
*/
spinlock_t spinlock;
/* flag to prevent spurious interrupts (which OHCI seems to
generate a lot :) from accessing the struct */
int dma_running;
/*
3) the sleeping semaphore 'sem' - this is used from process context only,
to serialize various operations on the video_card. Even though only one
......@@ -568,7 +572,7 @@ static inline int video_card_initialized(struct video_card *v)
static int do_dv1394_init(struct video_card *video, struct dv1394_init *init);
static int do_dv1394_init_default(struct video_card *video);
static int do_dv1394_shutdown(struct video_card *video, int free_user_buf);
static void do_dv1394_shutdown(struct video_card *video, int free_user_buf);
/* NTSC empty packet rate accurate to within 0.01%,
......
......@@ -689,7 +689,7 @@ static void frame_prepare(struct video_card *video, unsigned int this_frame)
wmb();
#endif
video->dma_running = 1;
/* set the 'run' bit */
reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, 0x8000);
......@@ -811,7 +811,9 @@ static void start_dma_receive(struct video_card *video)
reg_write(video->ohci, video->ohci_IsoRcvCommandPtr,
video->frames[0]->descriptor_pool_dma | 1); /* Z=1 */
wmb();
video->dma_running = 1;
/* run */
reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x8000);
flush_pci_write(video->ohci);
......@@ -912,16 +914,16 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
u64 chan_mask;
int retval = -EINVAL;
debug_printk( "dv1394: initialising %d\n", video->id );
debug_printk("dv1394: initialising %d\n", video->id);
if(init->api_version != DV1394_API_VERSION)
goto err;
return -EINVAL;
/* first sanitize all the parameters */
if( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) )
goto err;
return -EINVAL;
if( (init->format != DV1394_NTSC) && (init->format != DV1394_PAL) )
goto err;
return -EINVAL;
if( (init->syt_offset == 0) || (init->syt_offset > 50) )
/* default SYT offset is 3 cycles */
......@@ -942,15 +944,15 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
if(new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE);
/* don't allow the user to allocate the DMA buffer more than once */
if(video->dv_buf.kvirt && video->dv_buf_size != new_buf_size)
goto err;
if(video->dv_buf.kvirt && video->dv_buf_size != new_buf_size) {
printk("dv1394: re-sizing the DMA buffer is not allowed\n");
return -EINVAL;
}
/* shutdown the card if it's currently active */
/* (the card should not be reset if the parameters are screwy) */
if( video_card_initialized(video) )
do_dv1394_shutdown(video, 0);
do_dv1394_shutdown(video, 0);
/* try to claim the ISO channel */
spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
......@@ -967,7 +969,6 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
/* initialize misc. fields of video */
video->n_frames = init->n_frames;
video->pal_or_ntsc = init->format;
video->cip_accum = 0;
video->continuity_counter = 0;
......@@ -983,7 +984,6 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
video->current_packet = -1;
video->first_frame = 0;
if(video->pal_or_ntsc == DV1394_NTSC) {
video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_NTSC;
video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_NTSC;
......@@ -996,14 +996,8 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
video->syt_offset = init->syt_offset;
/* find and claim DMA contexts on the OHCI card */
/* XXX this should be the last step of initialization, since the interrupt
handler uses ohci_i*_ctx to indicate whether or not it is safe to touch
frames. I'm not making this change quite yet, since it would be better
to clean up the init/shutdown process first.*/
if(video->ohci_it_ctx == -1) {
ohci1394_init_iso_tasklet(&video->it_tasklet, OHCI_ISO_TRANSMIT,
it_tasklet_func, (unsigned long) video);
......@@ -1011,14 +1005,12 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
if (ohci1394_register_iso_tasklet(video->ohci, &video->it_tasklet) < 0) {
printk(KERN_ERR "dv1394: could not find an available IT DMA context\n");
retval = -EBUSY;
goto err_ctx;
}
else {
video->ohci_it_ctx = video->it_tasklet.context;
debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx);
goto err;
}
video->ohci_it_ctx = video->it_tasklet.context;
debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx);
}
if(video->ohci_ir_ctx == -1) {
ohci1394_init_iso_tasklet(&video->ir_tasklet, OHCI_ISO_RECEIVE,
......@@ -1027,14 +1019,11 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
if (ohci1394_register_iso_tasklet(video->ohci, &video->ir_tasklet) < 0) {
printk(KERN_ERR "dv1394: could not find an available IR DMA context\n");
retval = -EBUSY;
goto err_ctx;
}
else {
video->ohci_ir_ctx = video->ir_tasklet.context;
debug_printk("dv1394: claimed IR DMA context %d\n", video->ohci_ir_ctx);
goto err;
}
video->ohci_ir_ctx = video->ir_tasklet.context;
debug_printk("dv1394: claimed IR DMA context %d\n", video->ohci_ir_ctx);
}
/* allocate struct frames */
for(i = 0; i < init->n_frames; i++) {
......@@ -1043,7 +1032,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
if(!video->frames[i]) {
printk(KERN_ERR "dv1394: Cannot allocate frame structs\n");
retval = -ENOMEM;
goto err_frames;
goto err;
}
}
......@@ -1051,7 +1040,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
/* allocate the ringbuffer */
retval = dma_region_alloc(&video->dv_buf, new_buf_size, video->ohci->dev, PCI_DMA_TODEVICE);
if(retval)
goto err_frames;
goto err;
video->dv_buf_size = new_buf_size;
......@@ -1073,7 +1062,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
retval = dma_region_alloc(&video->packet_buf, video->packet_buf_size,
video->ohci->dev, PCI_DMA_FROMDEVICE);
if(retval)
goto err_dv_buf;
goto err;
debug_printk("dv1394: Allocated %d packets in buffer, total %u pages (%u DMA pages), %lu bytes\n",
video->n_frames*MAX_PACKETS, video->packet_buf.n_pages,
......@@ -1103,30 +1092,8 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
return 0;
err_dv_buf:
dma_region_free(&video->dv_buf);
err_frames:
for(i = 0; i < DV1394_MAX_FRAMES; i++) {
if(video->frames[i])
frame_delete(video->frames[i]);
}
video->n_frames = 0;
err_ctx:
if(video->ohci_it_ctx != -1) {
ohci1394_unregister_iso_tasklet(video->ohci, &video->it_tasklet);
video->ohci_it_ctx = -1;
}
if(video->ohci_ir_ctx != -1) {
ohci1394_unregister_iso_tasklet(video->ohci, &video->ir_tasklet);
video->ohci_ir_ctx = -1;
}
spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
video->ohci->ISO_channel_usage &= ~chan_mask;
spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
err:
err:
do_dv1394_shutdown(video, 1);
return retval;
}
......@@ -1154,10 +1121,15 @@ static void stop_dma(struct video_card *video)
{
unsigned long flags;
int i;
/* no interrupts */
spin_lock_irqsave(&video->spinlock, flags);
video->dma_running = 0;
if( (video->ohci_it_ctx == -1) && (video->ohci_ir_ctx == -1) )
goto out;
/* stop DMA if in progress */
if( (video->active_frame != -1) ||
(reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) ||
......@@ -1197,24 +1169,22 @@ static void stop_dma(struct video_card *video)
}
else
debug_printk("dv1394: stop_dma: already stopped.\n");
out:
spin_unlock_irqrestore(&video->spinlock, flags);
}
static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
static void do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
{
int i;
unsigned long flags;
debug_printk("dv1394: shutdown...\n");
/* stop DMA if in progress */
stop_dma(video);
spin_lock_irqsave(&video->spinlock, flags);
/* release the DMA contexts */
if(video->ohci_it_ctx != -1) {
video->ohci_IsoXmitContextControlSet = 0;
......@@ -1245,8 +1215,6 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
video->ohci_ir_ctx = -1;
}
spin_unlock_irqrestore(&video->spinlock, flags);
/* release the ISO channel */
if(video->channel != -1) {
u64 chan_mask;
......@@ -1282,9 +1250,7 @@ static int do_dv1394_shutdown(struct video_card *video, int free_dv_buf)
dma_region_free(&video->packet_buf);
video->packet_buf_size = 0;
debug_printk("dv1394: shutdown complete\n");
return 0;
debug_printk("dv1394: shutdown OK\n");
}
/*
......@@ -1770,7 +1736,8 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
}
case DV1394_IOC_SHUTDOWN:
ret = do_dv1394_shutdown(video, 0);
do_dv1394_shutdown(video, 0);
ret = 0;
break;
......@@ -2140,6 +2107,9 @@ static void it_tasklet_func(unsigned long data)
spin_lock(&video->spinlock);
if(!video->dma_running)
goto out;
irq_printk("ContextControl = %08x, CommandPtr = %08x\n",
reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
reg_read(video->ohci, video->ohci_IsoXmitCommandPtr)
......@@ -2266,14 +2236,15 @@ static void it_tasklet_func(unsigned long data)
} /* for(each frame) */
}
spin_unlock(&video->spinlock);
if(wake) {
kill_fasync(&video->fasync, SIGIO, POLL_OUT);
/* wake readers/writers/ioctl'ers */
wake_up_interruptible(&video->waitq);
}
out:
spin_unlock(&video->spinlock);
}
static void ir_tasklet_func(unsigned long data)
......@@ -2283,8 +2254,11 @@ static void ir_tasklet_func(unsigned long data)
spin_lock(&video->spinlock);
if( (video->ohci_ir_ctx != -1)
&& (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) )
if(!video->dma_running)
goto out;
if( (video->ohci_ir_ctx != -1) &&
(reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) )
{
int sof=0; /* start-of-frame flag */
......@@ -2424,14 +2398,15 @@ static void ir_tasklet_func(unsigned long data)
} /* receive interrupt */
spin_unlock(&video->spinlock);
if(wake) {
kill_fasync(&video->fasync, SIGIO, POLL_IN);
/* wake readers/writers/ioctl'ers */
wake_up_interruptible(&video->waitq);
}
out:
spin_unlock(&video->spinlock);
}
static struct file_operations dv1394_fops=
......@@ -2554,6 +2529,7 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes
clear_bit(0, &video->open);
spin_lock_init(&video->spinlock);
video->dma_running = 0;
init_MUTEX(&video->sem);
init_waitqueue_head(&video->waitq);
video->fasync = NULL;
......@@ -2565,7 +2541,7 @@ static int dv1394_init(struct ti_ohci *ohci, enum pal_or_ntsc format, enum modes
#ifdef CONFIG_DEVFS_FS
if (dv1394_devfs_add_entry(video) < 0)
goto err_free;
goto err_free;
#endif
debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id);
......@@ -2718,6 +2694,9 @@ static void dv1394_host_reset(struct hpsb_host *host)
spin_lock_irqsave(&video->spinlock, flags);
if(!video->dma_running)
goto out;
/* check IT context */
if(video->ohci_it_ctx != -1) {
u32 ctx;
......@@ -2790,7 +2769,8 @@ static void dv1394_host_reset(struct hpsb_host *host)
reg_read(video->ohci, video->ohci_IsoRcvCommandPtr));
}
}
out:
spin_unlock_irqrestore(&video->spinlock, flags);
/* wake readers/writers/ioctl'ers */
......
......@@ -78,7 +78,7 @@
printk(KERN_ERR fmt, ## args)
static char version[] __devinitdata =
"$Rev: 886 $ Ben Collins <bcollins@debian.org>";
"$Rev: 895 $ Ben Collins <bcollins@debian.org>";
/* Our ieee1394 highlevel driver */
#define ETHER1394_DRIVER_NAME "ether1394"
......@@ -340,6 +340,7 @@ static void ether1394_add_host (struct hpsb_host *host, struct hpsb_highlevel *h
priv = (struct eth1394_priv *)dev->priv;
priv->host = host;
spin_lock_init(&priv->lock);
hi = hpsb_create_hostinfo(hl, host, sizeof(*hi));
......
......@@ -38,7 +38,7 @@ struct hl_host_info {
static LIST_HEAD(hl_drivers);
static DECLARE_MUTEX(hl_drivers_lock);
static rwlock_t hl_drivers_lock = RW_LOCK_UNLOCKED;
static LIST_HEAD(addr_space);
static rwlock_t addr_space_lock = RW_LOCK_UNLOCKED;
......@@ -48,20 +48,22 @@ static struct hpsb_address_ops dummy_ops = { NULL, NULL, NULL, NULL };
static struct hpsb_address_serve dummy_zero_addr, dummy_max_addr;
/* Internal usage. Must be called with hl_drivers_lock held */
static struct hl_host_info *hl_get_hostinfo(struct hpsb_highlevel *hl,
struct hpsb_host *host)
{
struct hl_host_info *hi;
struct hl_host_info *hi = NULL;
struct list_head *lh;
read_lock(&hl->host_info_lock);
list_for_each (lh, &hl->host_info_list) {
hi = list_entry(lh, struct hl_host_info, list);
if (hi->host == host)
return hi;
break;
hi = NULL;
}
read_unlock(&hl->host_info_lock);
return NULL;
return hi;
}
......@@ -69,16 +71,12 @@ static struct hl_host_info *hl_get_hostinfo(struct hpsb_highlevel *hl,
* hpsb_create_hostinfo. */
void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host)
{
struct hl_host_info *hi;
void *data = NULL;
struct hl_host_info *hi = hl_get_hostinfo(hl, host);
read_lock(&hl_drivers_lock);
hi = hl_get_hostinfo(hl, host);
if (hi)
data = hi->data;
read_unlock(&hl_drivers_lock);
return hi->data;
return data;
return NULL;
}
......@@ -88,10 +86,9 @@ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
{
struct hl_host_info *hi;
void *data;
unsigned long flags;
read_lock(&hl_drivers_lock);
hi = hl_get_hostinfo(hl, host);
read_unlock(&hl_drivers_lock);
if (hi) {
HPSB_ERR("%s called hpsb_create_hostinfo when hostinfo already exists",
hl->name);
......@@ -112,9 +109,9 @@ void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
hi->host = host;
write_lock_irq(&hl_drivers_lock);
write_lock_irqsave(&hl->host_info_lock, flags);
list_add_tail(&hi->list, &hl->host_info_list);
write_unlock_irq(&hl_drivers_lock);
write_unlock_irqrestore(&hl->host_info_lock, flags);
return data;
}
......@@ -124,23 +121,20 @@ int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host,
void *data)
{
struct hl_host_info *hi;
int ret = -EINVAL;
write_lock_irq(&hl_drivers_lock);
hi = hl_get_hostinfo(hl, host);
if (hi) {
if (!hi->size && !hi->data) {
hi->data = data;
ret = 0;
return 0;
} else
HPSB_ERR("%s called hpsb_set_hostinfo when hostinfo already has data",
hl->name);
} else
HPSB_ERR("%s called hpsb_set_hostinfo when no hostinfo exists",
hl->name);
write_unlock_irq(&hl_drivers_lock);
return ret;
return -EINVAL;
}
......@@ -148,13 +142,14 @@ void hpsb_destroy_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host)
{
struct hl_host_info *hi;
write_lock_irq(&hl_drivers_lock);
hi = hl_get_hostinfo(hl, host);
if (hi) {
unsigned long flags;
write_lock_irqsave(&hl->host_info_lock, flags);
list_del(&hi->list);
write_unlock_irqrestore(&hl->host_info_lock, flags);
kfree(hi);
}
write_unlock_irq(&hl_drivers_lock);
return;
}
......@@ -164,11 +159,9 @@ void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host, un
{
struct hl_host_info *hi;
write_lock(&hl_drivers_lock);
hi = hl_get_hostinfo(hl, host);
if (hi)
hi->key = key;
write_unlock(&hl_drivers_lock);
return;
}
......@@ -177,15 +170,12 @@ void hpsb_set_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host, un
unsigned long hpsb_get_hostinfo_key(struct hpsb_highlevel *hl, struct hpsb_host *host)
{
struct hl_host_info *hi;
unsigned long key = 0;
read_lock(&hl_drivers_lock);
hi = hl_get_hostinfo(hl, host);
if (hi)
key = hi->key;
read_unlock(&hl_drivers_lock);
return hi->key;
return key;
return 0;
}
......@@ -195,7 +185,7 @@ void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key)
struct hl_host_info *hi;
void *data = NULL;
read_lock(&hl_drivers_lock);
read_lock(&hl->host_info_lock);
list_for_each (lh, &hl->host_info_list) {
hi = list_entry(lh, struct hl_host_info, list);
if (hi->key == key) {
......@@ -203,7 +193,7 @@ void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key)
break;
}
}
read_unlock(&hl_drivers_lock);
read_unlock(&hl->host_info_lock);
return data;
}
......@@ -214,6 +204,7 @@ struct hpsb_highlevel *hpsb_register_highlevel(const char *name,
{
struct hpsb_highlevel *hl;
struct list_head *lh;
unsigned long flags;
hl = (struct hpsb_highlevel *)kmalloc(sizeof(struct hpsb_highlevel),
GFP_KERNEL);
......@@ -225,12 +216,14 @@ struct hpsb_highlevel *hpsb_register_highlevel(const char *name,
INIT_LIST_HEAD(&hl->addr_list);
INIT_LIST_HEAD(&hl->host_info_list);
rwlock_init(&hl->host_info_lock);
hl->name = name;
hl->op = ops;
down(&hl_drivers_lock);
write_lock_irqsave(&hl_drivers_lock, flags);
list_add_tail(&hl->hl_list, &hl_drivers);
up(&hl_drivers_lock);
write_unlock_irqrestore(&hl_drivers_lock, flags);
if (hl->op->add_host) {
down(&hpsb_hosts_lock);
......@@ -248,22 +241,23 @@ void hpsb_unregister_highlevel(struct hpsb_highlevel *hl)
{
struct list_head *lh, *next;
struct hpsb_address_serve *as;
unsigned long flags;
if (hl == NULL) {
return;
}
write_lock_irq(&addr_space_lock);
write_lock_irqsave(&addr_space_lock, flags);
list_for_each_safe (lh, next, &hl->addr_list) {
as = list_entry(lh, struct hpsb_address_serve, addr_list);
list_del(&as->as_list);
kfree(as);
}
write_unlock_irq(&addr_space_lock);
write_unlock_irqrestore(&addr_space_lock, flags);
down(&hl_drivers_lock);
write_lock_irqsave(&hl_drivers_lock, flags);
list_del(&hl->hl_list);
up(&hl_drivers_lock);
write_unlock_irqrestore(&hl_drivers_lock, flags);
if (hl->op->remove_host) {
down(&hpsb_hosts_lock);
......@@ -307,8 +301,10 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
write_lock_irqsave(&addr_space_lock, flags);
entry = addr_space.next;
while (list_entry(entry, struct hpsb_address_serve, as_list)->end <= start) {
if (list_entry(entry->next, struct hpsb_address_serve, as_list)->start >= end) {
while (list_entry(entry, struct hpsb_address_serve, as_list)->end
<= start) {
if (list_entry(entry->next, struct hpsb_address_serve, as_list)
->start >= end) {
list_add(&as->as_list, entry);
list_add_tail(&as->addr_list, &hl->addr_list);
retval = 1;
......@@ -387,14 +383,13 @@ void highlevel_add_host(struct hpsb_host *host)
struct list_head *entry;
struct hpsb_highlevel *hl;
down(&hl_drivers_lock);
read_lock(&hl_drivers_lock);
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->add_host)
hl->op->add_host(host, hl);
}
up(&hl_drivers_lock);
read_unlock(&hl_drivers_lock);
}
void highlevel_remove_host(struct hpsb_host *host)
......@@ -402,7 +397,7 @@ void highlevel_remove_host(struct hpsb_host *host)
struct list_head *entry;
struct hpsb_highlevel *hl;
down(&hl_drivers_lock);
read_lock(&hl_drivers_lock);
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
......@@ -411,7 +406,7 @@ void highlevel_remove_host(struct hpsb_host *host)
hpsb_destroy_hostinfo(hl, host);
}
}
up(&hl_drivers_lock);
read_unlock(&hl_drivers_lock);
}
void highlevel_host_reset(struct hpsb_host *host)
......@@ -419,14 +414,14 @@ void highlevel_host_reset(struct hpsb_host *host)
struct list_head *entry;
struct hpsb_highlevel *hl;
down(&hl_drivers_lock);
read_lock(&hl_drivers_lock);
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->host_reset)
hl->op->host_reset(host);
}
up(&hl_drivers_lock);
read_unlock(&hl_drivers_lock);
}
void highlevel_iso_receive(struct hpsb_host *host, void *data,
......@@ -436,14 +431,17 @@ void highlevel_iso_receive(struct hpsb_host *host, void *data,
struct hpsb_highlevel *hl;
int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f;
down(&hl_drivers_lock);
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
read_lock(&hl_drivers_lock);
entry = hl_drivers.next;
if (hl->op->iso_receive)
while (entry != &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->iso_receive) {
hl->op->iso_receive(host, channel, data, length);
}
entry = entry->next;
}
up(&hl_drivers_lock);
read_unlock(&hl_drivers_lock);
}
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
......@@ -453,13 +451,18 @@ void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
struct hpsb_highlevel *hl;
int cts = ((quadlet_t *)data)[0] >> 4;
down(&hl_drivers_lock);
list_for_each(entry, &hl_drivers) {
read_lock(&hl_drivers_lock);
entry = hl_drivers.next;
while (entry != &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->fcp_request)
hl->op->fcp_request(host, nodeid, direction, cts, data, length);
if (hl->op->fcp_request) {
hl->op->fcp_request(host, nodeid, direction, cts, data,
length);
}
entry = entry->next;
}
up(&hl_drivers_lock);
read_unlock(&hl_drivers_lock);
}
int highlevel_read(struct hpsb_host *host, int nodeid, void *data,
......
......@@ -14,6 +14,7 @@ struct hpsb_highlevel {
/* Used by the highlevel drivers to store data per host */
struct list_head host_info_list;
rwlock_t host_info_lock;
};
......@@ -154,7 +155,7 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start);
* iso_receive op.
*/
int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel);
unsigned int channel);
void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
unsigned int channel);
......@@ -176,5 +177,4 @@ void *hpsb_get_hostinfo_bykey(struct hpsb_highlevel *hl, unsigned long key);
* hpsb_create_hostinfo, where the size is 0. */
int hpsb_set_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, void *data);
#endif /* IEEE1394_HIGHLEVEL_H */
......@@ -1295,7 +1295,6 @@ EXPORT_SYMBOL(highlevel_host_reset);
/** nodemgr.c **/
EXPORT_SYMBOL(hpsb_guid_get_entry);
EXPORT_SYMBOL(hpsb_nodeid_get_entry);
EXPORT_SYMBOL(hpsb_check_nodeid);
EXPORT_SYMBOL(hpsb_node_fill_packet);
EXPORT_SYMBOL(hpsb_node_read);
EXPORT_SYMBOL(hpsb_node_write);
......
......@@ -79,13 +79,13 @@ struct hpsb_tlabel_pool {
struct semaphore count;
};
#define HPSB_TPOOL_INIT(_tp) \
do { \
#define HPSB_TPOOL_INIT(_tp) \
do { \
CLEAR_BITMAP((_tp)->pool, 64); \
spin_lock_init(&(_tp)->lock); \
(_tp)->next = 0; \
spin_lock_init(&(_tp)->lock); \
(_tp)->next = 0; \
(_tp)->allocations = 0; \
sema_init(&(_tp)->count, 63); \
sema_init(&(_tp)->count, 63); \
} while(0)
......
......@@ -47,8 +47,11 @@ static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_i
int dma_direction;
/* make sure driver supports the ISO API */
if(!host->driver->isoctl)
if(!host->driver->isoctl) {
printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n",
host->driver->name);
return NULL;
}
/* sanitize parameters */
......
......@@ -1616,18 +1616,6 @@ struct node_entry *hpsb_nodeid_get_entry(struct hpsb_host *host, nodeid_t nodeid
return ne;
}
struct node_entry *hpsb_check_nodeid(struct hpsb_host *host, nodeid_t nodeid)
{
struct node_entry *ne;
if (down_trylock(&nodemgr_serialize))
return NULL;
ne = find_entry_by_nodeid(host, nodeid);
up(&nodemgr_serialize);
return ne;
}
/* The following four convenience functions use a struct node_entry
* for addressing a node on the bus. They are intended for use by any
* process context, not just the nodemgr thread, so we need to be a
......
......@@ -163,10 +163,6 @@ struct node_entry *hpsb_guid_get_entry(u64 guid);
* fool-proof by itself, since the nodeid can change. */
struct node_entry *hpsb_nodeid_get_entry(struct hpsb_host *host, nodeid_t nodeid);
/* Same as above except that it will not block waiting for the nodemgr
* serialize semaphore. */
struct node_entry *hpsb_check_nodeid(struct hpsb_host *host, nodeid_t nodeid);
/*
* If the entry refers to a local host, this function will return the pointer
* to the hpsb_host structure. It will return NULL otherwise. Once you have
......
......@@ -165,7 +165,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static char version[] __devinitdata =
"$Rev: 866 $ Ben Collins <bcollins@debian.org>";
"$Rev: 897 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
static int phys_dma = 1;
......
......@@ -1163,7 +1163,7 @@ static ssize_t mem_write(struct file *file, const char *buffer, size_t count,
********************************************************/
static void lynx_irq_handler(int irq, void *dev_id,
static irqreturn_t lynx_irq_handler(int irq, void *dev_id,
struct pt_regs *regs_are_unused)
{
struct ti_lynx *lynx = (struct ti_lynx *)dev_id;
......@@ -1174,7 +1174,8 @@ static void lynx_irq_handler(int irq, void *dev_id,
linkint = reg_read(lynx, LINK_INT_STATUS);
intmask = reg_read(lynx, PCI_INT_STATUS);
if (!(intmask & PCI_INT_INT_PEND)) return;
if (!(intmask & PCI_INT_INT_PEND))
return IRQ_HANDLED;
PRINTD(KERN_DEBUG, lynx->id, "interrupt: 0x%08x / 0x%08x", intmask,
linkint);
......@@ -1390,6 +1391,8 @@ static void lynx_irq_handler(int irq, void *dev_id,
run_pcl(lynx, lynx->rcv_pcl_start, CHANNEL_ASYNC_RCV);
}
return IRQ_HANDLED;
}
......@@ -1893,7 +1896,7 @@ static struct pci_driver lynx_pci_driver = {
.name = PCILYNX_DRIVER_NAME,
.id_table = pci_table,
.probe = add_card,
.remove = __devexit_p(remove_card),
.remove = remove_card,
};
static struct hpsb_host_driver lynx_driver = {
......
......@@ -298,7 +298,7 @@
#include "sbp2.h"
static char version[] __devinitdata =
"$Rev: 884 $ James Goodwin <jamesg@filanet.com>";
"$Rev: 896 $ James Goodwin <jamesg@filanet.com>";
/*
* Module load parameter definitions
......@@ -3040,10 +3040,10 @@ static int sbp2scsi_proc_info(char *buffer, char **start, off_t offset,
SPRINTF("Driver version : %s\n", version);
SPRINTF("\nModule options :\n");
SPRINTF(" max_speed : %s\n", hpsb_speedto_str[max_speed]);
SPRINTF(" max_sectors : %d\n", max_sectors);
SPRINTF(" serialize_io : %s\n", serialize_io ? "yes" : "no");
SPRINTF(" exclusive_login : %s\n", exclusive_login ? "yes" : "no");
SPRINTF(" max_speed : %s\n", hpsb_speedto_str[max_speed]);
SPRINTF(" max_sectors : %d\n", max_sectors);
SPRINTF(" serialize_io : %s\n", serialize_io ? "yes" : "no");
SPRINTF(" exclusive_login : %s\n", exclusive_login ? "yes" : "no");
SPRINTF("\nAttached devices : %s\n", !list_empty(&host->my_devices) ?
"" : "none");
......
......@@ -67,14 +67,6 @@
#define vmalloc_32(x) vmalloc(x)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,3))
#define remap_page_range_1394(vma, start, addr, size, prot) \
remap_page_range(start, addr, size, prot)
#else
#define remap_page_range_1394(vma, start, addr, size, prot) \
remap_page_range(vma, start, addr, size, prot)
#endif
struct it_dma_prg {
struct dma_cmd begin;
quadlet_t data[4];
......@@ -496,11 +488,7 @@ void wakeup_dma_ir_ctx(unsigned long l)
if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) {
reset_ir_status(d, i);
d->buffer_status[i] = VIDEO1394_BUFFER_READY;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)
get_fast_time(&d->buffer_time[i]);
#else
do_gettimeofday(&d->buffer_time[i]);
#endif
}
}
......
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