diff options
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r-- | drivers/ieee1394/Kconfig | 5 | ||||
-rw-r--r-- | drivers/ieee1394/dv1394.c | 6 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_core.c | 15 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_core.h | 3 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_transactions.c | 3 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_transactions.h | 7 | ||||
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 32 | ||||
-rw-r--r-- | drivers/ieee1394/ohci1394.c | 2 | ||||
-rw-r--r-- | drivers/ieee1394/ohci1394.h | 3 | ||||
-rw-r--r-- | drivers/ieee1394/pcilynx.c | 394 | ||||
-rw-r--r-- | drivers/ieee1394/pcilynx.h | 49 | ||||
-rw-r--r-- | drivers/ieee1394/raw1394.c | 10 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.c | 156 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.h | 4 | ||||
-rw-r--r-- | drivers/ieee1394/video1394.c | 143 |
15 files changed, 157 insertions, 675 deletions
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig index 78b201fb5e8a..7d58af1ae306 100644 --- a/drivers/ieee1394/Kconfig +++ b/drivers/ieee1394/Kconfig @@ -84,11 +84,6 @@ config IEEE1394_PCILYNX To compile this driver as a module, say M here: the module will be called pcilynx. -# Non-maintained pcilynx options -# if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then -# bool ' Use PCILynx local RAM' CONFIG_IEEE1394_PCILYNX_LOCALRAM -# bool ' Support for non-IEEE1394 local ports' CONFIG_IEEE1394_PCILYNX_PORTS -# fi config IEEE1394_OHCI1394 tristate "OHCI-1394 support" depends on PCI && IEEE1394 diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 68c7a5f07842..4538b0235ca3 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c @@ -2343,8 +2343,8 @@ static void dv1394_remove_host (struct hpsb_host *host) dv1394_un_init(video); } while (video != NULL); - class_simple_device_remove(MKDEV( - IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2))); + class_device_destroy(hpsb_protocol_class, + MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2))); devfs_remove("ieee1394/dv/host%d/NTSC", id); devfs_remove("ieee1394/dv/host%d/PAL", id); devfs_remove("ieee1394/dv/host%d", id); @@ -2361,7 +2361,7 @@ static void dv1394_add_host (struct hpsb_host *host) ohci = (struct ti_ohci *)host->hostdata; - class_simple_device_add(hpsb_protocol_class, MKDEV( + class_device_create(hpsb_protocol_class, MKDEV( IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL, "dv1394-%d", id); devfs_mk_dir("ieee1394/dv/host%d", id); diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 1c5845f7e4ab..629070b83a33 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -67,7 +67,7 @@ MODULE_LICENSE("GPL"); /* Some globals used */ const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" }; -struct class_simple *hpsb_protocol_class; +struct class *hpsb_protocol_class; #ifdef CONFIG_IEEE1394_VERBOSEDEBUG static void dump_packet(const char *text, quadlet_t *data, int size) @@ -520,7 +520,7 @@ int hpsb_send_packet(struct hpsb_packet *packet) if (!packet->no_waiter || packet->expect_response) { atomic_inc(&packet->refcnt); - packet->sendtime = jiffies; + packet->sendtime = jiffies + 10 * HZ; skb_queue_tail(&host->pending_packet_queue, packet->skb); } @@ -1041,10 +1041,8 @@ static int hpsbpkt_thread(void *__hi) while (1) { if (down_interruptible(&khpsbpkt_sig)) { - if (current->flags & PF_FREEZE) { - refrigerator(0); + if (try_to_freeze()) continue; - } printk("khpsbpkt: received unexpected signal?!\n" ); break; } @@ -1121,7 +1119,7 @@ static int __init ieee1394_init(void) if (ret < 0) goto release_all_bus; - hpsb_protocol_class = class_simple_create(THIS_MODULE, "ieee1394_protocol"); + hpsb_protocol_class = class_create(THIS_MODULE, "ieee1394_protocol"); if (IS_ERR(hpsb_protocol_class)) { ret = PTR_ERR(hpsb_protocol_class); goto release_class_host; @@ -1159,7 +1157,7 @@ static int __init ieee1394_init(void) cleanup_csr: cleanup_csr(); release_class_protocol: - class_simple_destroy(hpsb_protocol_class); + class_destroy(hpsb_protocol_class); release_class_host: class_unregister(&hpsb_host_class); release_all_bus: @@ -1189,7 +1187,7 @@ static void __exit ieee1394_cleanup(void) cleanup_csr(); - class_simple_destroy(hpsb_protocol_class); + class_destroy(hpsb_protocol_class); class_unregister(&hpsb_host_class); for (i = 0; fw_bus_attrs[i]; i++) bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); @@ -1248,7 +1246,6 @@ EXPORT_SYMBOL(hpsb_make_phypacket); EXPORT_SYMBOL(hpsb_make_isopacket); EXPORT_SYMBOL(hpsb_read); EXPORT_SYMBOL(hpsb_write); -EXPORT_SYMBOL(hpsb_lock); EXPORT_SYMBOL(hpsb_packet_success); /** highlevel.c **/ diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h index c4b4408e2e05..73bd8efd2b6c 100644 --- a/drivers/ieee1394/ieee1394_core.h +++ b/drivers/ieee1394/ieee1394_core.h @@ -223,6 +223,7 @@ extern int hpsb_disable_irm; /* Our sysfs bus entry */ extern struct bus_type ieee1394_bus_type; extern struct class hpsb_host_class; -extern struct class_simple *hpsb_protocol_class; +extern struct class *hpsb_protocol_class; #endif /* _IEEE1394_CORE_H */ + diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 09908b9564d8..0aa876360f9b 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c @@ -535,6 +535,7 @@ hpsb_write_fail: return retval; } +#if 0 int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, u64 addr, int extcode, quadlet_t *data, quadlet_t arg) @@ -599,3 +600,5 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, return retval; } + +#endif /* 0 */ diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h index 526a43ceb496..45ba784fe6da 100644 --- a/drivers/ieee1394/ieee1394_transactions.h +++ b/drivers/ieee1394/ieee1394_transactions.h @@ -53,12 +53,5 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation, u64 addr, quadlet_t *buffer, size_t length); int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, u64 addr, quadlet_t *buffer, size_t length); -int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, - u64 addr, int extcode, quadlet_t *data, quadlet_t arg); -int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation, - u64 addr, int extcode, octlet_t *data, octlet_t arg); -int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, - quadlet_t *buffer, size_t length, u32 specifier_id, - unsigned int version); #endif /* _IEEE1394_TRANSACTIONS_H */ diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index a1e30a66297b..9a46c3b44bf8 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -220,7 +220,7 @@ struct device nodemgr_dev_template_host = { #define fw_attr(class, class_type, field, type, format_string) \ -static ssize_t fw_show_##class##_##field (struct device *dev, char *buf)\ +static ssize_t fw_show_##class##_##field (struct device *dev, struct device_attribute *attr, char *buf)\ { \ class_type *class; \ class = container_of(dev, class_type, device); \ @@ -232,7 +232,7 @@ static struct device_attribute dev_attr_##class##_##field = { \ }; #define fw_attr_td(class, class_type, td_kv) \ -static ssize_t fw_show_##class##_##td_kv (struct device *dev, char *buf)\ +static ssize_t fw_show_##class##_##td_kv (struct device *dev, struct device_attribute *attr, char *buf)\ { \ int len; \ class_type *class = container_of(dev, class_type, device); \ @@ -265,7 +265,7 @@ static struct driver_attribute driver_attr_drv_##field = { \ }; -static ssize_t fw_show_ne_bus_options(struct device *dev, char *buf) +static ssize_t fw_show_ne_bus_options(struct device *dev, struct device_attribute *attr, char *buf) { struct node_entry *ne = container_of(dev, struct node_entry, device); @@ -281,7 +281,7 @@ static ssize_t fw_show_ne_bus_options(struct device *dev, char *buf) static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL); -static ssize_t fw_show_ne_tlabels_free(struct device *dev, char *buf) +static ssize_t fw_show_ne_tlabels_free(struct device *dev, struct device_attribute *attr, char *buf) { struct node_entry *ne = container_of(dev, struct node_entry, device); return sprintf(buf, "%d\n", atomic_read(&ne->tpool->count.count) + 1); @@ -289,7 +289,7 @@ static ssize_t fw_show_ne_tlabels_free(struct device *dev, char *buf) static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL); -static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, char *buf) +static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, struct device_attribute *attr, char *buf) { struct node_entry *ne = container_of(dev, struct node_entry, device); return sprintf(buf, "%u\n", ne->tpool->allocations); @@ -297,7 +297,7 @@ static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, char *buf) static DEVICE_ATTR(tlabels_allocations,S_IRUGO,fw_show_ne_tlabels_allocations,NULL); -static ssize_t fw_show_ne_tlabels_mask(struct device *dev, char *buf) +static ssize_t fw_show_ne_tlabels_mask(struct device *dev, struct device_attribute *attr, char *buf) { struct node_entry *ne = container_of(dev, struct node_entry, device); #if (BITS_PER_LONG <= 32) @@ -309,7 +309,7 @@ static ssize_t fw_show_ne_tlabels_mask(struct device *dev, char *buf) static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL); -static ssize_t fw_set_ignore_driver(struct device *dev, const char *buf, size_t count) +static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct unit_directory *ud = container_of(dev, struct unit_directory, device); int state = simple_strtoul(buf, NULL, 10); @@ -324,7 +324,7 @@ static ssize_t fw_set_ignore_driver(struct device *dev, const char *buf, size_t return count; } -static ssize_t fw_get_ignore_driver(struct device *dev, char *buf) +static ssize_t fw_get_ignore_driver(struct device *dev, struct device_attribute *attr, char *buf) { struct unit_directory *ud = container_of(dev, struct unit_directory, device); @@ -695,14 +695,15 @@ static void nodemgr_remove_ne(struct node_entry *ne) put_device(dev); } +static int __nodemgr_remove_host_dev(struct device *dev, void *data) +{ + nodemgr_remove_ne(container_of(dev, struct node_entry, device)); + return 0; +} static void nodemgr_remove_host_dev(struct device *dev) { - struct device *ne_dev, *next; - - list_for_each_entry_safe(ne_dev, next, &dev->children, node) - nodemgr_remove_ne(container_of(ne_dev, struct node_entry, device)); - + device_for_each_child(dev, NULL, __nodemgr_remove_host_dev); sysfs_remove_link(&dev->kobj, "irm_id"); sysfs_remove_link(&dev->kobj, "busmgr_id"); sysfs_remove_link(&dev->kobj, "host_id"); @@ -1005,8 +1006,7 @@ static struct unit_directory *nodemgr_process_unit_directory return ud; unit_directory_error: - if (ud != NULL) - kfree(ud); + kfree(ud); return NULL; } @@ -1510,7 +1510,7 @@ static int nodemgr_host_thread(void *__hi) if (down_interruptible(&hi->reset_sem) || down_interruptible(&nodemgr_serialize)) { - if (try_to_freeze(PF_FREEZE)) + if (try_to_freeze()) continue; printk("NodeMgr: received unexpected signal?!\n" ); break; diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 6cb0b586c297..36e25ac823dc 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -2931,7 +2931,7 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) kfree(d->prg_cpu); kfree(d->prg_bus); } - if (d->spb) kfree(d->spb); + kfree(d->spb); /* Mark this context as freed. */ d->ohci = NULL; diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h index d1758d409610..cc66c1cae250 100644 --- a/drivers/ieee1394/ohci1394.h +++ b/drivers/ieee1394/ohci1394.h @@ -236,6 +236,9 @@ struct ti_ohci { static inline int cross_bound(unsigned long addr, unsigned int size) { + if (size == 0) + return 0; + if (size > PAGE_SIZE) return 1; diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index a261d2b0e5ac..bdb3a85cafa6 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c @@ -43,6 +43,7 @@ #include <linux/fs.h> #include <linux/poll.h> #include <linux/kdev_t.h> +#include <linux/dma-mapping.h> #include <asm/byteorder.h> #include <asm/atomic.h> #include <asm/io.h> @@ -834,327 +835,6 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) * IEEE-1394 functionality section END * ***************************************/ -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS -/* VFS functions for local bus / aux device access. Access to those - * is implemented as a character device instead of block devices - * because buffers are not wanted for this. Therefore llseek (from - * VFS) can be used for these char devices with obvious effects. - */ -static int mem_open(struct inode*, struct file*); -static int mem_release(struct inode*, struct file*); -static unsigned int aux_poll(struct file*, struct poll_table_struct*); -static loff_t mem_llseek(struct file*, loff_t, int); -static ssize_t mem_read (struct file*, char*, size_t, loff_t*); -static ssize_t mem_write(struct file*, const char*, size_t, loff_t*); - - -static struct file_operations aux_ops = { - .owner = THIS_MODULE, - .read = mem_read, - .write = mem_write, - .poll = aux_poll, - .llseek = mem_llseek, - .open = mem_open, - .release = mem_release, -}; - - -static void aux_setup_pcls(struct ti_lynx *lynx) -{ - struct ti_pcl pcl; - - pcl.next = PCL_NEXT_INVALID; - pcl.user_data = pcl_bus(lynx, lynx->dmem_pcl); - put_pcl(lynx, lynx->dmem_pcl, &pcl); -} - -static int mem_open(struct inode *inode, struct file *file) -{ - int cid = iminor(inode); - enum { t_rom, t_aux, t_ram } type; - struct memdata *md; - - if (cid < PCILYNX_MINOR_AUX_START) { - /* just for completeness */ - return -ENXIO; - } else if (cid < PCILYNX_MINOR_ROM_START) { - cid -= PCILYNX_MINOR_AUX_START; - if (cid >= num_of_cards || !cards[cid].aux_port) - return -ENXIO; - type = t_aux; - } else if (cid < PCILYNX_MINOR_RAM_START) { - cid -= PCILYNX_MINOR_ROM_START; - if (cid >= num_of_cards || !cards[cid].local_rom) - return -ENXIO; - type = t_rom; - } else { - /* WARNING: Know what you are doing when opening RAM. - * It is currently used inside the driver! */ - cid -= PCILYNX_MINOR_RAM_START; - if (cid >= num_of_cards || !cards[cid].local_ram) - return -ENXIO; - type = t_ram; - } - - md = (struct memdata *)kmalloc(sizeof(struct memdata), SLAB_KERNEL); - if (md == NULL) - return -ENOMEM; - - md->lynx = &cards[cid]; - md->cid = cid; - - switch (type) { - case t_rom: - md->type = rom; - break; - case t_ram: - md->type = ram; - break; - case t_aux: - atomic_set(&md->aux_intr_last_seen, - atomic_read(&cards[cid].aux_intr_seen)); - md->type = aux; - break; - } - - file->private_data = md; - - return 0; -} - -static int mem_release(struct inode *inode, struct file *file) -{ - kfree(file->private_data); - return 0; -} - -static unsigned int aux_poll(struct file *file, poll_table *pt) -{ - struct memdata *md = (struct memdata *)file->private_data; - int cid = md->cid; - unsigned int mask; - - /* reading and writing is always allowed */ - mask = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM; - - if (md->type == aux) { - poll_wait(file, &cards[cid].aux_intr_wait, pt); - - if (atomic_read(&md->aux_intr_last_seen) - != atomic_read(&cards[cid].aux_intr_seen)) { - mask |= POLLPRI; - atomic_inc(&md->aux_intr_last_seen); - } - } - - return mask; -} - -loff_t mem_llseek(struct file *file, loff_t offs, int orig) -{ - loff_t newoffs; - - switch (orig) { - case 0: - newoffs = offs; - break; - case 1: - newoffs = offs + file->f_pos; - break; - case 2: - newoffs = PCILYNX_MAX_MEMORY + 1 + offs; - break; - default: - return -EINVAL; - } - - if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) return -EINVAL; - - file->f_pos = newoffs; - return newoffs; -} - -/* - * do not DMA if count is too small because this will have a serious impact - * on performance - the value 2400 was found by experiment and may not work - * everywhere as good as here - use mem_mindma option for modules to change - */ -static short mem_mindma = 2400; -module_param(mem_mindma, short, 0444); -MODULE_PARM_DESC(mem_mindma, "Minimum amount of data required to use DMA"); - -static ssize_t mem_dmaread(struct memdata *md, u32 physbuf, ssize_t count, - int offset) -{ - pcltmp_t pcltmp; - struct ti_pcl *pcl; - size_t retval; - int i; - DECLARE_WAITQUEUE(wait, current); - - count &= ~3; - count = min(count, 53196); - retval = count; - - if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) - & DMA_CHAN_CTRL_BUSY) { - PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!"); - } - - reg_write(md->lynx, LBUS_ADDR, md->type | offset); - - pcl = edit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); - pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | min(count, 4092); - pcl->buffer[0].pointer = physbuf; - count -= 4092; - - i = 0; - while (count > 0) { - i++; - pcl->buffer[i].control = min(count, 4092); - pcl->buffer[i].pointer = physbuf + i * 4092; - count -= 4092; - } - pcl->buffer[i].control |= PCL_LAST_BUFF; - commit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); - run_sub_pcl(md->lynx, md->lynx->dmem_pcl, 2, CHANNEL_LOCALBUS); - - schedule(); - while (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) - & DMA_CHAN_CTRL_BUSY) { - if (signal_pending(current)) { - retval = -EINTR; - break; - } - schedule(); - } - - reg_write(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS), 0); - remove_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); - - if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) - & DMA_CHAN_CTRL_BUSY) { - PRINT(KERN_ERR, md->lynx->id, "DMA STILL ACTIVE!"); - } - - return retval; -} - -static ssize_t mem_read(struct file *file, char *buffer, size_t count, - loff_t *offset) -{ - struct memdata *md = (struct memdata *)file->private_data; - ssize_t bcount; - size_t alignfix; - loff_t off = *offset; /* avoid useless 64bit-arithmetic */ - ssize_t retval; - void *membase; - - if ((off + count) > PCILYNX_MAX_MEMORY+1) { - count = PCILYNX_MAX_MEMORY+1 - off; - } - if (count == 0 || off > PCILYNX_MAX_MEMORY) { - return -ENOSPC; - } - - switch (md->type) { - case rom: - membase = md->lynx->local_rom; - break; - case ram: - membase = md->lynx->local_ram; - break; - case aux: - membase = md->lynx->aux_port; - break; - default: - panic("pcilynx%d: unsupported md->type %d in %s", - md->lynx->id, md->type, __FUNCTION__); - } - - down(&md->lynx->mem_dma_mutex); - - if (count < mem_mindma) { - memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, count); - goto out; - } - - bcount = count; - alignfix = 4 - (off % 4); - if (alignfix != 4) { - if (bcount < alignfix) { - alignfix = bcount; - } - memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, - alignfix); - if (bcount == alignfix) { - goto out; - } - bcount -= alignfix; - off += alignfix; - } - - while (bcount >= 4) { - retval = mem_dmaread(md, md->lynx->mem_dma_buffer_dma - + count - bcount, bcount, off); - if (retval < 0) return retval; - - bcount -= retval; - off += retval; - } - - if (bcount) { - memcpy_fromio(md->lynx->mem_dma_buffer + count - bcount, - membase+off, bcount); - } - - out: - retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count); - up(&md->lynx->mem_dma_mutex); - - if (retval) return -EFAULT; - *offset += count; - return count; -} - - -static ssize_t mem_write(struct file *file, const char *buffer, size_t count, - loff_t *offset) -{ - struct memdata *md = (struct memdata *)file->private_data; - - if (((*offset) + count) > PCILYNX_MAX_MEMORY+1) { - count = PCILYNX_MAX_MEMORY+1 - *offset; - } - if (count == 0 || *offset > PCILYNX_MAX_MEMORY) { - return -ENOSPC; - } - - /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */ - switch (md->type) { - case aux: - if (copy_from_user(md->lynx->aux_port+(*offset), buffer, count)) - return -EFAULT; - break; - case ram: - if (copy_from_user(md->lynx->local_ram+(*offset), buffer, count)) - return -EFAULT; - break; - case rom: - /* the ROM may be writeable */ - if (copy_from_user(md->lynx->local_rom+(*offset), buffer, count)) - return -EFAULT; - break; - } - - file->f_pos += count; - return count; -} -#endif /* CONFIG_IEEE1394_PCILYNX_PORTS */ - /******************************************************** * Global stuff (interrupt handler, init/shutdown code) * @@ -1181,18 +861,6 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id, reg_write(lynx, LINK_INT_STATUS, linkint); reg_write(lynx, PCI_INT_STATUS, intmask); -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS - if (intmask & PCI_INT_AUX_INT) { - atomic_inc(&lynx->aux_intr_seen); - wake_up_interruptible(&lynx->aux_intr_wait); - } - - if (intmask & PCI_INT_DMA_HLT(CHANNEL_LOCALBUS)) { - wake_up_interruptible(&lynx->mem_dma_intr_wait); - } -#endif - - if (intmask & PCI_INT_1394) { if (linkint & LINK_INT_PHY_TIMEOUT) { PRINT(KERN_INFO, lynx->id, "PHY timeout occurred"); @@ -1484,15 +1152,9 @@ static void remove_card(struct pci_dev *dev) pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page, lynx->rcv_page_dma); case have_aux_buf: -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS - pci_free_consistent(lynx->dev, 65536, lynx->mem_dma_buffer, - lynx->mem_dma_buffer_dma); -#endif case have_pcl_mem: -#ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem, lynx->pcl_mem_dma); -#endif case clear: /* do nothing - already freed */ ; @@ -1524,7 +1186,7 @@ static int __devinit add_card(struct pci_dev *dev, error = -ENXIO; - if (pci_set_dma_mask(dev, 0xffffffff)) + if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) FAIL("DMA address limits not supported for PCILynx hardware"); if (pci_enable_device(dev)) FAIL("failed to enable PCILynx hardware"); @@ -1546,7 +1208,6 @@ static int __devinit add_card(struct pci_dev *dev, spin_lock_init(&lynx->lock); spin_lock_init(&lynx->phy_reg_lock); -#ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE, &lynx->pcl_mem_dma); @@ -1558,16 +1219,6 @@ static int __devinit add_card(struct pci_dev *dev, } else { FAIL("failed to allocate PCL memory area"); } -#endif - -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS - lynx->mem_dma_buffer = pci_alloc_consistent(dev, 65536, - &lynx->mem_dma_buffer_dma); - if (lynx->mem_dma_buffer == NULL) { - FAIL("failed to allocate DMA buffer for aux"); - } - lynx->state = have_aux_buf; -#endif lynx->rcv_page = pci_alloc_consistent(dev, PAGE_SIZE, &lynx->rcv_page_dma); @@ -1597,13 +1248,6 @@ static int __devinit add_card(struct pci_dev *dev, FAIL("failed to remap registers - card not accessible"); } -#ifdef CONFIG_IEEE1394_PCILYNX_LOCALRAM - if (lynx->local_ram == NULL) { - FAIL("failed to remap local RAM which is required for " - "operation"); - } -#endif - reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); /* Fix buggy cards with autoboot pin not tied low: */ reg_write(lynx, DMA0_CHAN_CTRL, 0); @@ -1624,13 +1268,6 @@ static int __devinit add_card(struct pci_dev *dev, /* alloc_pcl return values are not checked, it is expected that the * provided PCL space is sufficient for the initial allocations */ -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS - if (lynx->aux_port != NULL) { - lynx->dmem_pcl = alloc_pcl(lynx); - aux_setup_pcls(lynx); - sema_init(&lynx->mem_dma_mutex, 1); - } -#endif lynx->rcv_pcl = alloc_pcl(lynx); lynx->rcv_pcl_start = alloc_pcl(lynx); lynx->async.pcl = alloc_pcl(lynx); @@ -1647,12 +1284,6 @@ static int __devinit add_card(struct pci_dev *dev, reg_write(lynx, PCI_INT_ENABLE, PCI_INT_DMA_ALL); -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS - reg_set_bits(lynx, PCI_INT_ENABLE, PCI_INT_AUX_INT); - init_waitqueue_head(&lynx->mem_dma_intr_wait); - init_waitqueue_head(&lynx->aux_intr_wait); -#endif - tasklet_init(&lynx->iso_rcv.tq, (void (*)(unsigned long))iso_rcv_bh, (unsigned long)lynx); @@ -1944,37 +1575,18 @@ static int __init pcilynx_init(void) { int ret; -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS - if (register_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME, &aux_ops)) { - PRINT_G(KERN_ERR, "allocation of char major number %d failed", - PCILYNX_MAJOR); - return -EBUSY; - } -#endif - ret = pci_register_driver(&lynx_pci_driver); if (ret < 0) { PRINT_G(KERN_ERR, "PCI module init failed"); - goto free_char_dev; + return ret; } return 0; - - free_char_dev: -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS - unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME); -#endif - - return ret; } static void __exit pcilynx_cleanup(void) { pci_unregister_driver(&lynx_pci_driver); - -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS - unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME); -#endif } diff --git a/drivers/ieee1394/pcilynx.h b/drivers/ieee1394/pcilynx.h index 644ec55d3d46..d631aa8383ad 100644 --- a/drivers/ieee1394/pcilynx.h +++ b/drivers/ieee1394/pcilynx.h @@ -55,16 +55,6 @@ struct ti_lynx { void __iomem *aux_port; quadlet_t bus_info_block[5]; -#ifdef CONFIG_IEEE1394_PCILYNX_PORTS - atomic_t aux_intr_seen; - wait_queue_head_t aux_intr_wait; - - void *mem_dma_buffer; - dma_addr_t mem_dma_buffer_dma; - struct semaphore mem_dma_mutex; - wait_queue_head_t mem_dma_intr_wait; -#endif - /* * use local RAM of LOCALRAM_SIZE bytes for PCLs, which allows for * LOCALRAM_SIZE * 8 PCLs (each sized 128 bytes); @@ -72,11 +62,9 @@ struct ti_lynx { */ u8 pcl_bmap[LOCALRAM_SIZE / 1024]; -#ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM /* point to PCLs memory area if needed */ void *pcl_mem; dma_addr_t pcl_mem_dma; -#endif /* PCLs for local mem / aux transfers */ pcl_t dmem_pcl; @@ -378,39 +366,6 @@ struct ti_pcl { #define pcloffs(MEMBER) (offsetof(struct ti_pcl, MEMBER)) -#ifdef CONFIG_IEEE1394_PCILYNX_LOCALRAM - -static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid, - const struct ti_pcl *pcl) -{ - int i; - u32 *in = (u32 *)pcl; - u32 *out = (u32 *)(lynx->local_ram + pclid * sizeof(struct ti_pcl)); - - for (i = 0; i < 32; i++, out++, in++) { - writel(*in, out); - } -} - -static inline void get_pcl(const struct ti_lynx *lynx, pcl_t pclid, - struct ti_pcl *pcl) -{ - int i; - u32 *out = (u32 *)pcl; - u32 *in = (u32 *)(lynx->local_ram + pclid * sizeof(struct ti_pcl)); - - for (i = 0; i < 32; i++, out++, in++) { - *out = readl(in); - } -} - -static inline u32 pcl_bus(const struct ti_lynx *lynx, pcl_t pclid) -{ - return pci_resource_start(lynx->dev, 1) + pclid * sizeof(struct ti_pcl); -} - -#else /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */ - static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid, const struct ti_pcl *pcl) { @@ -431,10 +386,8 @@ static inline u32 pcl_bus(const struct ti_lynx *lynx, pcl_t pclid) return lynx->pcl_mem_dma + pclid * sizeof(struct ti_pcl); } -#endif /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */ - -#if defined (CONFIG_IEEE1394_PCILYNX_LOCALRAM) || defined (__BIG_ENDIAN) +#if defined (__BIG_ENDIAN) typedef struct ti_pcl pcltmp_t; static inline struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid, diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 6a08a8982ea8..7419af450bd1 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -2901,7 +2901,7 @@ static int __init init_raw1394(void) hpsb_register_highlevel(&raw1394_highlevel); - if (IS_ERR(class_simple_device_add(hpsb_protocol_class, MKDEV( + if (IS_ERR(class_device_create(hpsb_protocol_class, MKDEV( IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL, RAW1394_DEVICE_NAME))) { ret = -EFAULT; @@ -2934,8 +2934,8 @@ static int __init init_raw1394(void) out_dev: devfs_remove(RAW1394_DEVICE_NAME); - class_simple_device_remove(MKDEV( - IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); + class_device_destroy(hpsb_protocol_class, + MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); out_unreg: hpsb_unregister_highlevel(&raw1394_highlevel); out: @@ -2944,8 +2944,8 @@ out: static void __exit cleanup_raw1394(void) { - class_simple_device_remove(MKDEV( - IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); + class_device_destroy(hpsb_protocol_class, + MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)); cdev_del(&raw1394_cdev); devfs_remove(RAW1394_DEVICE_NAME); hpsb_unregister_highlevel(&raw1394_highlevel); diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 00c7b958361a..32368f3428ec 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -745,7 +745,8 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids); /* Register our host with the SCSI stack. */ - scsi_host = scsi_host_alloc(&scsi_driver_template, 0); + scsi_host = scsi_host_alloc(&scsi_driver_template, + sizeof (unsigned long)); if (!scsi_host) { SBP2_ERR("failed to register scsi host"); goto failed_alloc; @@ -1070,7 +1071,7 @@ static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_ static __inline__ int sbp2_command_conversion_device_type(u8 device_type) { return (((device_type == TYPE_DISK) || - (device_type == TYPE_SDAD) || + (device_type == TYPE_RBC) || (device_type == TYPE_ROM)) ? 1:0); } @@ -2111,102 +2112,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, */ static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd) { - unchar new_cmd[16]; - u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun); - - SBP2_DEBUG("sbp2_check_sbp2_command"); - - switch (*cmd) { - - case READ_6: - - if (sbp2_command_conversion_device_type(device_type)) { - - SBP2_DEBUG("Convert READ_6 to READ_10"); - - /* - * Need to turn read_6 into read_10 - */ - new_cmd[0] = 0x28; - new_cmd[1] = (cmd[1] & 0xe0); - new_cmd[2] = 0x0; - new_cmd[3] = (cmd[1] & 0x1f); - new_cmd[4] = cmd[2]; - new_cmd[5] = cmd[3]; - new_cmd[6] = 0x0; - new_cmd[7] = 0x0; - new_cmd[8] = cmd[4]; - new_cmd[9] = cmd[5]; - - memcpy(cmd, new_cmd, 10); - - } - - break; - - case WRITE_6: - - if (sbp2_command_conversion_device_type(device_type)) { - - SBP2_DEBUG("Convert WRITE_6 to WRITE_10"); - - /* - * Need to turn write_6 into write_10 - */ - new_cmd[0] = 0x2a; - new_cmd[1] = (cmd[1] & 0xe0); - new_cmd[2] = 0x0; - new_cmd[3] = (cmd[1] & 0x1f); - new_cmd[4] = cmd[2]; - new_cmd[5] = cmd[3]; - new_cmd[6] = 0x0; - new_cmd[7] = 0x0; - new_cmd[8] = cmd[4]; - new_cmd[9] = cmd[5]; - - memcpy(cmd, new_cmd, 10); - - } - - break; - - case MODE_SENSE: - - if (sbp2_command_conversion_device_type(device_type)) { - - SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10"); - - /* - * Need to turn mode_sense_6 into mode_sense_10 - */ - new_cmd[0] = 0x5a; - new_cmd[1] = cmd[1]; - new_cmd[2] = cmd[2]; - new_cmd[3] = 0x0; - new_cmd[4] = 0x0; - new_cmd[5] = 0x0; - new_cmd[6] = 0x0; - new_cmd[7] = 0x0; - new_cmd[8] = cmd[4]; - new_cmd[9] = cmd[5]; - - memcpy(cmd, new_cmd, 10); - - } - - break; - - case MODE_SELECT: - - /* - * TODO. Probably need to change mode select to 10 byte version - */ - - default: - break; - } - - return; } /* @@ -2247,7 +2152,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, struct scsi_cmnd *SCpnt) { u8 *scsi_buf = SCpnt->request_buffer; - u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun); SBP2_DEBUG("sbp2_check_sbp2_response"); @@ -2272,14 +2176,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, } /* - * Check for Simple Direct Access Device and change it to TYPE_DISK - */ - if ((scsi_buf[0] & 0x1f) == TYPE_SDAD) { - SBP2_DEBUG("Changing TYPE_SDAD to TYPE_DISK"); - scsi_buf[0] &= 0xe0; - } - - /* * Fix ansi revision and response data format */ scsi_buf[2] |= 2; @@ -2287,27 +2183,6 @@ static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, break; - case MODE_SENSE: - - if (sbp2_command_conversion_device_type(device_type)) { - - SBP2_DEBUG("Modify mode sense response (10 byte version)"); - - scsi_buf[0] = scsi_buf[1]; /* Mode data length */ - scsi_buf[1] = scsi_buf[2]; /* Medium type */ - scsi_buf[2] = scsi_buf[3]; /* Device specific parameter */ - scsi_buf[3] = scsi_buf[7]; /* Block descriptor length */ - memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]); - } - - break; - - case MODE_SELECT: - - /* - * TODO. Probably need to change mode select to 10 byte version - */ - default: break; } @@ -2579,8 +2454,6 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, u32 scsi_status, struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { - unsigned long flags; - SBP2_DEBUG("sbp2scsi_complete_command"); /* @@ -2679,18 +2552,15 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, /* * Tell scsi stack that we're done with this command */ - spin_lock_irqsave(scsi_id->scsi_host->host_lock,flags); done (SCpnt); - spin_unlock_irqrestore(scsi_id->scsi_host->host_lock,flags); - - return; } static int sbp2scsi_slave_configure (struct scsi_device *sdev) { blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); - + sdev->use_10_for_rw = 1; + sdev->use_10_for_ms = 1; return 0; } @@ -2746,7 +2616,7 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt) /* * Called by scsi stack when something has really gone wrong. */ -static int sbp2scsi_reset(struct scsi_cmnd *SCpnt) +static int __sbp2scsi_reset(struct scsi_cmnd *SCpnt) { struct scsi_id_instance_data *scsi_id = (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; @@ -2761,12 +2631,24 @@ static int sbp2scsi_reset(struct scsi_cmnd *SCpnt) return(SUCCESS); } +static int sbp2scsi_reset(struct scsi_cmnd *SCpnt) +{ + unsigned long flags; + int rc; + + spin_lock_irqsave(SCpnt->device->host->host_lock, flags); + rc = __sbp2scsi_reset(SCpnt); + spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); + + return rc; +} + static const char *sbp2scsi_info (struct Scsi_Host *host) { return "SCSI emulation for IEEE-1394 SBP-2 Devices"; } -static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, char *buf) +static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_device *sdev; struct scsi_id_instance_data *scsi_id; diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index a84b039a05b9..cd425be74841 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h @@ -266,10 +266,6 @@ struct sbp2_status_block { #define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */ #define SBP2_MAX_SECTORS 255 /* Max sectors supported */ -#ifndef TYPE_SDAD -#define TYPE_SDAD 0x0e /* simplified direct access device */ -#endif - /* * SCSI direction table... * (now used as a back-up in case the direction passed down from above is "unknown") diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 4bedf7113f40..06759b36afea 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -35,6 +35,11 @@ * */ +/* Markus Tavenrath <speedygoo@speedygoo.de> : + - fixed checks for valid buffer-numbers in video1394_icotl + - changed the ways the dma prg's are used, now it's possible to use + even a single dma buffer +*/ #include <linux/config.h> #include <linux/kernel.h> #include <linux/list.h> @@ -112,6 +117,7 @@ struct dma_iso_ctx { struct it_dma_prg **it_prg; unsigned int *buffer_status; + unsigned int *buffer_prg_assignment; struct timeval *buffer_time; /* time when the buffer was received */ unsigned int *last_used_cmd; /* For ISO Transmit with variable sized packets only ! */ @@ -180,23 +186,14 @@ static int free_dma_iso_ctx(struct dma_iso_ctx *d) kfree(d->prg_reg); } - if (d->ir_prg) - kfree(d->ir_prg); - - if (d->it_prg) - kfree(d->it_prg); - - if (d->buffer_status) - kfree(d->buffer_status); - if (d->buffer_time) - kfree(d->buffer_time); - if (d->last_used_cmd) - kfree(d->last_used_cmd); - if (d->next_buffer) - kfree(d->next_buffer); - + kfree(d->ir_prg); + kfree(d->it_prg); + kfree(d->buffer_status); + kfree(d->buffer_prg_assignment); + kfree(d->buffer_time); + kfree(d->last_used_cmd); + kfree(d->next_buffer); list_del(&d->link); - kfree(d); return 0; @@ -230,7 +227,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, /* Init the regions for easy cleanup */ dma_region_init(&d->dma); - if (dma_region_alloc(&d->dma, d->num_desc * d->buf_size, ohci->dev, + if (dma_region_alloc(&d->dma, (d->num_desc - 1) * d->buf_size, ohci->dev, PCI_DMA_BIDIRECTIONAL)) { PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma buffer"); free_dma_iso_ctx(d); @@ -342,6 +339,8 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int), GFP_KERNEL); + d->buffer_prg_assignment = kmalloc(d->num_desc * sizeof(unsigned int), + GFP_KERNEL); d->buffer_time = kmalloc(d->num_desc * sizeof(struct timeval), GFP_KERNEL); d->last_used_cmd = kmalloc(d->num_desc * sizeof(unsigned int), @@ -354,6 +353,11 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, free_dma_iso_ctx(d); return NULL; } + if (d->buffer_prg_assignment == NULL) { + PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_prg_assignment"); + free_dma_iso_ctx(d); + return NULL; + } if (d->buffer_time == NULL) { PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_time"); free_dma_iso_ctx(d); @@ -370,6 +374,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, return NULL; } memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int)); + memset(d->buffer_prg_assignment, 0, d->num_desc * sizeof(unsigned int)); memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval)); memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int)); memset(d->next_buffer, -1, d->num_desc * sizeof(int)); @@ -379,7 +384,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, PRINT(KERN_INFO, ohci->host->id, "Iso %s DMA: %d buffers " "of size %d allocated for a frame size %d, each with %d prgs", (type == OHCI_ISO_RECEIVE) ? "receive" : "transmit", - d->num_desc, d->buf_size, d->frame_size, d->nb_cmd); + d->num_desc - 1, d->buf_size, d->frame_size, d->nb_cmd); return d; } @@ -394,11 +399,36 @@ static void reset_ir_status(struct dma_iso_ctx *d, int n) d->ir_prg[n][i].status = cpu_to_le32(d->left_size); } +static void reprogram_dma_ir_prg(struct dma_iso_ctx *d, int n, int buffer, int flags) +{ + struct dma_cmd *ir_prg = d->ir_prg[n]; + unsigned long buf = (unsigned long)d->dma.kvirt + buffer * d->buf_size; + int i; + + d->buffer_prg_assignment[n] = buffer; + + ir_prg[0].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, buf - + (unsigned long)d->dma.kvirt)); + ir_prg[1].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, + (buf + 4) - (unsigned long)d->dma.kvirt)); + + for (i=2;i<d->nb_cmd-1;i++) { + ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, + (buf+(i-1)*PAGE_SIZE) - + (unsigned long)d->dma.kvirt)); + } + + ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | + DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size); + ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, + (buf+(i-1)*PAGE_SIZE) - (unsigned long)d->dma.kvirt)); +} + static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags) { struct dma_cmd *ir_prg = d->ir_prg[n]; struct dma_prog_region *ir_reg = &d->prg_reg[n]; - unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size; + unsigned long buf = (unsigned long)d->dma.kvirt; int i; /* the first descriptor will read only 4 bytes */ @@ -508,7 +538,7 @@ static void wakeup_dma_ir_ctx(unsigned long l) for (i = 0; i < d->num_desc; i++) { 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; + d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY; do_gettimeofday(&d->buffer_time[i]); } } @@ -585,7 +615,7 @@ static void wakeup_dma_it_ctx(unsigned long l) int next = d->next_buffer[i]; put_timestamp(ohci, d, next); d->it_prg[i][d->last_used_cmd[i]].end.status = 0; - d->buffer_status[i] = VIDEO1394_BUFFER_READY; + d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY; } } @@ -595,11 +625,25 @@ static void wakeup_dma_it_ctx(unsigned long l) wake_up_interruptible(&d->waitq); } +static void reprogram_dma_it_prg(struct dma_iso_ctx *d, int n, int buffer) +{ + struct it_dma_prg *it_prg = d->it_prg[n]; + unsigned long buf = (unsigned long)d->dma.kvirt + buffer * d->buf_size; + int i; + + d->buffer_prg_assignment[n] = buffer; + for (i=0;i<d->nb_cmd;i++) { + it_prg[i].end.address = + cpu_to_le32(dma_region_offset_to_bus(&d->dma, + (buf+i*d->packet_size) - (unsigned long)d->dma.kvirt)); + } +} + static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag) { struct it_dma_prg *it_prg = d->it_prg[n]; struct dma_prog_region *it_reg = &d->prg_reg[n]; - unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size; + unsigned long buf = (unsigned long)d->dma.kvirt; int i; d->last_used_cmd[n] = d->nb_cmd - 1; for (i=0;i<d->nb_cmd;i++) { @@ -796,7 +840,7 @@ static int __video1394_ioctl(struct file *file, if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL) { d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE, - v.nb_buffers, v.buf_size, + v.nb_buffers + 1, v.buf_size, v.channel, 0); if (d == NULL) { @@ -817,7 +861,7 @@ static int __video1394_ioctl(struct file *file, } else { d = alloc_dma_iso_ctx(ohci, OHCI_ISO_TRANSMIT, - v.nb_buffers, v.buf_size, + v.nb_buffers + 1, v.buf_size, v.channel, v.packet_size); if (d == NULL) { @@ -889,6 +933,7 @@ static int __video1394_ioctl(struct file *file, { struct video1394_wait v; struct dma_iso_ctx *d; + int next_prg; if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; @@ -896,7 +941,7 @@ static int __video1394_ioctl(struct file *file, d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); if (d == NULL) return -EFAULT; - if ((v.buffer<0) || (v.buffer>d->num_desc)) { + if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) { PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EINVAL; @@ -913,12 +958,14 @@ static int __video1394_ioctl(struct file *file, d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; + next_prg = (d->last_buffer + 1) % d->num_desc; if (d->last_buffer>=0) d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = - cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) + cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0) & 0xfffffff0) | 0x1); - d->last_buffer = v.buffer; + d->last_buffer = next_prg; + reprogram_dma_ir_prg(d, d->last_buffer, v.buffer, d->flags); d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = 0; @@ -930,7 +977,7 @@ static int __video1394_ioctl(struct file *file, /* Tell the controller where the first program is */ reg_write(ohci, d->cmdPtr, - dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x1); + dma_prog_region_offset_to_bus(&d->prg_reg[d->last_buffer], 0) | 0x1); /* Run IR context */ reg_write(ohci, d->ctrlSet, 0x8000); @@ -951,7 +998,7 @@ static int __video1394_ioctl(struct file *file, { struct video1394_wait v; struct dma_iso_ctx *d; - int i; + int i = 0; if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; @@ -959,7 +1006,7 @@ static int __video1394_ioctl(struct file *file, d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); if (d == NULL) return -EFAULT; - if ((v.buffer<0) || (v.buffer>d->num_desc)) { + if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) { PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EINVAL; @@ -1005,9 +1052,9 @@ static int __video1394_ioctl(struct file *file, * Look ahead to see how many more buffers have been received */ i=0; - while (d->buffer_status[(v.buffer+1)%d->num_desc]== + while (d->buffer_status[(v.buffer+1)%(d->num_desc - 1)]== VIDEO1394_BUFFER_READY) { - v.buffer=(v.buffer+1)%d->num_desc; + v.buffer=(v.buffer+1)%(d->num_desc - 1); i++; } spin_unlock_irqrestore(&d->lock, flags); @@ -1023,6 +1070,7 @@ static int __video1394_ioctl(struct file *file, struct video1394_wait v; unsigned int *psizes = NULL; struct dma_iso_ctx *d; + int next_prg; if (copy_from_user(&v, argp, sizeof(v))) return -EFAULT; @@ -1030,7 +1078,7 @@ static int __video1394_ioctl(struct file *file, d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); if (d == NULL) return -EFAULT; - if ((v.buffer<0) || (v.buffer>d->num_desc)) { + if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) { PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EINVAL; @@ -1056,19 +1104,19 @@ static int __video1394_ioctl(struct file *file, spin_lock_irqsave(&d->lock,flags); + // last_buffer is last_prg + next_prg = (d->last_buffer + 1) % d->num_desc; if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) { PRINT(KERN_ERR, ohci->host->id, "Buffer %d is already used",v.buffer); spin_unlock_irqrestore(&d->lock,flags); - if (psizes) - kfree(psizes); + kfree(psizes); return -EBUSY; } if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { initialize_dma_it_prg_var_packet_queue( - d, v.buffer, psizes, - ohci); + d, next_prg, psizes, ohci); } d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; @@ -1076,16 +1124,17 @@ static int __video1394_ioctl(struct file *file, if (d->last_buffer >= 0) { d->it_prg[d->last_buffer] [ d->last_used_cmd[d->last_buffer] ].end.branchAddress = - cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], + cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0) & 0xfffffff0) | 0x3); d->it_prg[d->last_buffer] [ d->last_used_cmd[d->last_buffer] ].begin.branchAddress = - cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], + cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0) & 0xfffffff0) | 0x3); - d->next_buffer[d->last_buffer] = v.buffer; + d->next_buffer[d->last_buffer] = (v.buffer + 1) % (d->num_desc - 1); } - d->last_buffer = v.buffer; + d->last_buffer = next_prg; + reprogram_dma_it_prg(d, d->last_buffer, v.buffer); d->next_buffer[d->last_buffer] = -1; d->it_prg[d->last_buffer][d->last_used_cmd[d->last_buffer]].end.branchAddress = 0; @@ -1100,7 +1149,7 @@ static int __video1394_ioctl(struct file *file, /* Tell the controller where the first program is */ reg_write(ohci, d->cmdPtr, - dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x3); + dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0) | 0x3); /* Run IT context */ reg_write(ohci, d->ctrlSet, 0x8000); @@ -1116,9 +1165,7 @@ static int __video1394_ioctl(struct file *file, } } - if (psizes) - kfree(psizes); - + kfree(psizes); return 0; } @@ -1133,7 +1180,7 @@ static int __video1394_ioctl(struct file *file, d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); if (d == NULL) return -EFAULT; - if ((v.buffer<0) || (v.buffer>d->num_desc)) { + if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) { PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EINVAL; @@ -1323,7 +1370,7 @@ static void video1394_add_host (struct hpsb_host *host) hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; - class_simple_device_add(hpsb_protocol_class, MKDEV( + class_device_create(hpsb_protocol_class, MKDEV( IEEE1394_MAJOR, minor), NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor), @@ -1337,7 +1384,7 @@ static void video1394_remove_host (struct hpsb_host *host) struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host); if (ohci) { - class_simple_device_remove(MKDEV(IEEE1394_MAJOR, + class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id); } |