diff options
Diffstat (limited to 'drivers/ieee1394')
| -rw-r--r-- | drivers/ieee1394/Kconfig | 5 | ||||
| -rw-r--r-- | drivers/ieee1394/ieee1394_core.c | 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 | 3 | ||||
| -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/video1394.c | 139 |
10 files changed, 106 insertions, 502 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 | |||
| 84 | To compile this driver as a module, say M here: the | 84 | To compile this driver as a module, say M here: the |
| 85 | module will be called pcilynx. | 85 | module will be called pcilynx. |
| 86 | 86 | ||
| 87 | # Non-maintained pcilynx options | ||
| 88 | # if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then | ||
| 89 | # bool ' Use PCILynx local RAM' CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
| 90 | # bool ' Support for non-IEEE1394 local ports' CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 91 | # fi | ||
| 92 | config IEEE1394_OHCI1394 | 87 | config IEEE1394_OHCI1394 |
| 93 | tristate "OHCI-1394 support" | 88 | tristate "OHCI-1394 support" |
| 94 | depends on PCI && IEEE1394 | 89 | depends on PCI && IEEE1394 |
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 1c5845f7e4ab..a294e45c77cd 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c | |||
| @@ -520,7 +520,7 @@ int hpsb_send_packet(struct hpsb_packet *packet) | |||
| 520 | 520 | ||
| 521 | if (!packet->no_waiter || packet->expect_response) { | 521 | if (!packet->no_waiter || packet->expect_response) { |
| 522 | atomic_inc(&packet->refcnt); | 522 | atomic_inc(&packet->refcnt); |
| 523 | packet->sendtime = jiffies; | 523 | packet->sendtime = jiffies + 10 * HZ; |
| 524 | skb_queue_tail(&host->pending_packet_queue, packet->skb); | 524 | skb_queue_tail(&host->pending_packet_queue, packet->skb); |
| 525 | } | 525 | } |
| 526 | 526 | ||
| @@ -1248,7 +1248,6 @@ EXPORT_SYMBOL(hpsb_make_phypacket); | |||
| 1248 | EXPORT_SYMBOL(hpsb_make_isopacket); | 1248 | EXPORT_SYMBOL(hpsb_make_isopacket); |
| 1249 | EXPORT_SYMBOL(hpsb_read); | 1249 | EXPORT_SYMBOL(hpsb_read); |
| 1250 | EXPORT_SYMBOL(hpsb_write); | 1250 | EXPORT_SYMBOL(hpsb_write); |
| 1251 | EXPORT_SYMBOL(hpsb_lock); | ||
| 1252 | EXPORT_SYMBOL(hpsb_packet_success); | 1251 | EXPORT_SYMBOL(hpsb_packet_success); |
| 1253 | 1252 | ||
| 1254 | /** highlevel.c **/ | 1253 | /** highlevel.c **/ |
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: | |||
| 535 | return retval; | 535 | return retval; |
| 536 | } | 536 | } |
| 537 | 537 | ||
| 538 | #if 0 | ||
| 538 | 539 | ||
| 539 | int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, | 540 | int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, |
| 540 | u64 addr, int extcode, quadlet_t *data, quadlet_t arg) | 541 | 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, | |||
| 599 | 600 | ||
| 600 | return retval; | 601 | return retval; |
| 601 | } | 602 | } |
| 603 | |||
| 604 | #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, | |||
| 53 | u64 addr, quadlet_t *buffer, size_t length); | 53 | u64 addr, quadlet_t *buffer, size_t length); |
| 54 | int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, | 54 | int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, |
| 55 | u64 addr, quadlet_t *buffer, size_t length); | 55 | u64 addr, quadlet_t *buffer, size_t length); |
| 56 | int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, | ||
| 57 | u64 addr, int extcode, quadlet_t *data, quadlet_t arg); | ||
| 58 | int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation, | ||
| 59 | u64 addr, int extcode, octlet_t *data, octlet_t arg); | ||
| 60 | int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, | ||
| 61 | quadlet_t *buffer, size_t length, u32 specifier_id, | ||
| 62 | unsigned int version); | ||
| 63 | 56 | ||
| 64 | #endif /* _IEEE1394_TRANSACTIONS_H */ | 57 | #endif /* _IEEE1394_TRANSACTIONS_H */ |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index a1e30a66297b..83e66ed97ab5 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
| @@ -1005,8 +1005,7 @@ static struct unit_directory *nodemgr_process_unit_directory | |||
| 1005 | return ud; | 1005 | return ud; |
| 1006 | 1006 | ||
| 1007 | unit_directory_error: | 1007 | unit_directory_error: |
| 1008 | if (ud != NULL) | 1008 | kfree(ud); |
| 1009 | kfree(ud); | ||
| 1010 | return NULL; | 1009 | return NULL; |
| 1011 | } | 1010 | } |
| 1012 | 1011 | ||
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) | |||
| 2931 | kfree(d->prg_cpu); | 2931 | kfree(d->prg_cpu); |
| 2932 | kfree(d->prg_bus); | 2932 | kfree(d->prg_bus); |
| 2933 | } | 2933 | } |
| 2934 | if (d->spb) kfree(d->spb); | 2934 | kfree(d->spb); |
| 2935 | 2935 | ||
| 2936 | /* Mark this context as freed. */ | 2936 | /* Mark this context as freed. */ |
| 2937 | d->ohci = NULL; | 2937 | 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 { | |||
| 236 | 236 | ||
| 237 | static inline int cross_bound(unsigned long addr, unsigned int size) | 237 | static inline int cross_bound(unsigned long addr, unsigned int size) |
| 238 | { | 238 | { |
| 239 | if (size == 0) | ||
| 240 | return 0; | ||
| 241 | |||
| 239 | if (size > PAGE_SIZE) | 242 | if (size > PAGE_SIZE) |
| 240 | return 1; | 243 | return 1; |
| 241 | 244 | ||
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 @@ | |||
| 43 | #include <linux/fs.h> | 43 | #include <linux/fs.h> |
| 44 | #include <linux/poll.h> | 44 | #include <linux/poll.h> |
| 45 | #include <linux/kdev_t.h> | 45 | #include <linux/kdev_t.h> |
| 46 | #include <linux/dma-mapping.h> | ||
| 46 | #include <asm/byteorder.h> | 47 | #include <asm/byteorder.h> |
| 47 | #include <asm/atomic.h> | 48 | #include <asm/atomic.h> |
| 48 | #include <asm/io.h> | 49 | #include <asm/io.h> |
| @@ -834,327 +835,6 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) | |||
| 834 | * IEEE-1394 functionality section END * | 835 | * IEEE-1394 functionality section END * |
| 835 | ***************************************/ | 836 | ***************************************/ |
| 836 | 837 | ||
| 837 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 838 | /* VFS functions for local bus / aux device access. Access to those | ||
| 839 | * is implemented as a character device instead of block devices | ||
| 840 | * because buffers are not wanted for this. Therefore llseek (from | ||
| 841 | * VFS) can be used for these char devices with obvious effects. | ||
| 842 | */ | ||
| 843 | static int mem_open(struct inode*, struct file*); | ||
| 844 | static int mem_release(struct inode*, struct file*); | ||
| 845 | static unsigned int aux_poll(struct file*, struct poll_table_struct*); | ||
| 846 | static loff_t mem_llseek(struct file*, loff_t, int); | ||
| 847 | static ssize_t mem_read (struct file*, char*, size_t, loff_t*); | ||
| 848 | static ssize_t mem_write(struct file*, const char*, size_t, loff_t*); | ||
| 849 | |||
| 850 | |||
| 851 | static struct file_operations aux_ops = { | ||
| 852 | .owner = THIS_MODULE, | ||
| 853 | .read = mem_read, | ||
| 854 | .write = mem_write, | ||
| 855 | .poll = aux_poll, | ||
| 856 | .llseek = mem_llseek, | ||
| 857 | .open = mem_open, | ||
| 858 | .release = mem_release, | ||
| 859 | }; | ||
| 860 | |||
| 861 | |||
| 862 | static void aux_setup_pcls(struct ti_lynx *lynx) | ||
| 863 | { | ||
| 864 | struct ti_pcl pcl; | ||
| 865 | |||
| 866 | pcl.next = PCL_NEXT_INVALID; | ||
| 867 | pcl.user_data = pcl_bus(lynx, lynx->dmem_pcl); | ||
| 868 | put_pcl(lynx, lynx->dmem_pcl, &pcl); | ||
| 869 | } | ||
| 870 | |||
| 871 | static int mem_open(struct inode *inode, struct file *file) | ||
| 872 | { | ||
| 873 | int cid = iminor(inode); | ||
| 874 | enum { t_rom, t_aux, t_ram } type; | ||
| 875 | struct memdata *md; | ||
| 876 | |||
| 877 | if (cid < PCILYNX_MINOR_AUX_START) { | ||
| 878 | /* just for completeness */ | ||
| 879 | return -ENXIO; | ||
| 880 | } else if (cid < PCILYNX_MINOR_ROM_START) { | ||
| 881 | cid -= PCILYNX_MINOR_AUX_START; | ||
| 882 | if (cid >= num_of_cards || !cards[cid].aux_port) | ||
| 883 | return -ENXIO; | ||
| 884 | type = t_aux; | ||
| 885 | } else if (cid < PCILYNX_MINOR_RAM_START) { | ||
| 886 | cid -= PCILYNX_MINOR_ROM_START; | ||
| 887 | if (cid >= num_of_cards || !cards[cid].local_rom) | ||
| 888 | return -ENXIO; | ||
| 889 | type = t_rom; | ||
| 890 | } else { | ||
| 891 | /* WARNING: Know what you are doing when opening RAM. | ||
| 892 | * It is currently used inside the driver! */ | ||
| 893 | cid -= PCILYNX_MINOR_RAM_START; | ||
| 894 | if (cid >= num_of_cards || !cards[cid].local_ram) | ||
| 895 | return -ENXIO; | ||
| 896 | type = t_ram; | ||
| 897 | } | ||
| 898 | |||
| 899 | md = (struct memdata *)kmalloc(sizeof(struct memdata), SLAB_KERNEL); | ||
| 900 | if (md == NULL) | ||
| 901 | return -ENOMEM; | ||
| 902 | |||
| 903 | md->lynx = &cards[cid]; | ||
| 904 | md->cid = cid; | ||
| 905 | |||
| 906 | switch (type) { | ||
| 907 | case t_rom: | ||
| 908 | md->type = rom; | ||
| 909 | break; | ||
| 910 | case t_ram: | ||
| 911 | md->type = ram; | ||
| 912 | break; | ||
| 913 | case t_aux: | ||
| 914 | atomic_set(&md->aux_intr_last_seen, | ||
| 915 | atomic_read(&cards[cid].aux_intr_seen)); | ||
| 916 | md->type = aux; | ||
| 917 | break; | ||
| 918 | } | ||
| 919 | |||
| 920 | file->private_data = md; | ||
| 921 | |||
| 922 | return 0; | ||
| 923 | } | ||
| 924 | |||
| 925 | static int mem_release(struct inode *inode, struct file *file) | ||
| 926 | { | ||
| 927 | kfree(file->private_data); | ||
| 928 | return 0; | ||
| 929 | } | ||
| 930 | |||
| 931 | static unsigned int aux_poll(struct file *file, poll_table *pt) | ||
| 932 | { | ||
| 933 | struct memdata *md = (struct memdata *)file->private_data; | ||
| 934 | int cid = md->cid; | ||
| 935 | unsigned int mask; | ||
| 936 | |||
| 937 | /* reading and writing is always allowed */ | ||
| 938 | mask = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM; | ||
| 939 | |||
| 940 | if (md->type == aux) { | ||
| 941 | poll_wait(file, &cards[cid].aux_intr_wait, pt); | ||
| 942 | |||
| 943 | if (atomic_read(&md->aux_intr_last_seen) | ||
| 944 | != atomic_read(&cards[cid].aux_intr_seen)) { | ||
| 945 | mask |= POLLPRI; | ||
| 946 | atomic_inc(&md->aux_intr_last_seen); | ||
| 947 | } | ||
| 948 | } | ||
| 949 | |||
| 950 | return mask; | ||
| 951 | } | ||
| 952 | |||
| 953 | loff_t mem_llseek(struct file *file, loff_t offs, int orig) | ||
| 954 | { | ||
| 955 | loff_t newoffs; | ||
| 956 | |||
| 957 | switch (orig) { | ||
| 958 | case 0: | ||
| 959 | newoffs = offs; | ||
| 960 | break; | ||
| 961 | case 1: | ||
| 962 | newoffs = offs + file->f_pos; | ||
| 963 | break; | ||
| 964 | case 2: | ||
| 965 | newoffs = PCILYNX_MAX_MEMORY + 1 + offs; | ||
| 966 | break; | ||
| 967 | default: | ||
| 968 | return -EINVAL; | ||
| 969 | } | ||
| 970 | |||
| 971 | if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) return -EINVAL; | ||
| 972 | |||
| 973 | file->f_pos = newoffs; | ||
| 974 | return newoffs; | ||
| 975 | } | ||
| 976 | |||
| 977 | /* | ||
| 978 | * do not DMA if count is too small because this will have a serious impact | ||
| 979 | * on performance - the value 2400 was found by experiment and may not work | ||
| 980 | * everywhere as good as here - use mem_mindma option for modules to change | ||
| 981 | */ | ||
| 982 | static short mem_mindma = 2400; | ||
| 983 | module_param(mem_mindma, short, 0444); | ||
| 984 | MODULE_PARM_DESC(mem_mindma, "Minimum amount of data required to use DMA"); | ||
| 985 | |||
| 986 | static ssize_t mem_dmaread(struct memdata *md, u32 physbuf, ssize_t count, | ||
| 987 | int offset) | ||
| 988 | { | ||
| 989 | pcltmp_t pcltmp; | ||
| 990 | struct ti_pcl *pcl; | ||
| 991 | size_t retval; | ||
| 992 | int i; | ||
| 993 | DECLARE_WAITQUEUE(wait, current); | ||
| 994 | |||
| 995 | count &= ~3; | ||
| 996 | count = min(count, 53196); | ||
| 997 | retval = count; | ||
| 998 | |||
| 999 | if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) | ||
| 1000 | & DMA_CHAN_CTRL_BUSY) { | ||
| 1001 | PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!"); | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | reg_write(md->lynx, LBUS_ADDR, md->type | offset); | ||
| 1005 | |||
| 1006 | pcl = edit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); | ||
| 1007 | pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | min(count, 4092); | ||
| 1008 | pcl->buffer[0].pointer = physbuf; | ||
| 1009 | count -= 4092; | ||
| 1010 | |||
| 1011 | i = 0; | ||
| 1012 | while (count > 0) { | ||
| 1013 | i++; | ||
| 1014 | pcl->buffer[i].control = min(count, 4092); | ||
| 1015 | pcl->buffer[i].pointer = physbuf + i * 4092; | ||
| 1016 | count -= 4092; | ||
| 1017 | } | ||
| 1018 | pcl->buffer[i].control |= PCL_LAST_BUFF; | ||
| 1019 | commit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); | ||
| 1020 | |||
| 1021 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1022 | add_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); | ||
| 1023 | run_sub_pcl(md->lynx, md->lynx->dmem_pcl, 2, CHANNEL_LOCALBUS); | ||
| 1024 | |||
| 1025 | schedule(); | ||
| 1026 | while (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) | ||
| 1027 | & DMA_CHAN_CTRL_BUSY) { | ||
| 1028 | if (signal_pending(current)) { | ||
| 1029 | retval = -EINTR; | ||
| 1030 | break; | ||
| 1031 | } | ||
| 1032 | schedule(); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | reg_write(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS), 0); | ||
| 1036 | remove_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); | ||
| 1037 | |||
| 1038 | if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) | ||
| 1039 | & DMA_CHAN_CTRL_BUSY) { | ||
| 1040 | PRINT(KERN_ERR, md->lynx->id, "DMA STILL ACTIVE!"); | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | return retval; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | static ssize_t mem_read(struct file *file, char *buffer, size_t count, | ||
| 1047 | loff_t *offset) | ||
| 1048 | { | ||
| 1049 | struct memdata *md = (struct memdata *)file->private_data; | ||
| 1050 | ssize_t bcount; | ||
| 1051 | size_t alignfix; | ||
| 1052 | loff_t off = *offset; /* avoid useless 64bit-arithmetic */ | ||
| 1053 | ssize_t retval; | ||
| 1054 | void *membase; | ||
| 1055 | |||
| 1056 | if ((off + count) > PCILYNX_MAX_MEMORY+1) { | ||
| 1057 | count = PCILYNX_MAX_MEMORY+1 - off; | ||
| 1058 | } | ||
| 1059 | if (count == 0 || off > PCILYNX_MAX_MEMORY) { | ||
| 1060 | return -ENOSPC; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | switch (md->type) { | ||
| 1064 | case rom: | ||
| 1065 | membase = md->lynx->local_rom; | ||
| 1066 | break; | ||
| 1067 | case ram: | ||
| 1068 | membase = md->lynx->local_ram; | ||
| 1069 | break; | ||
| 1070 | case aux: | ||
| 1071 | membase = md->lynx->aux_port; | ||
| 1072 | break; | ||
| 1073 | default: | ||
| 1074 | panic("pcilynx%d: unsupported md->type %d in %s", | ||
| 1075 | md->lynx->id, md->type, __FUNCTION__); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | down(&md->lynx->mem_dma_mutex); | ||
| 1079 | |||
| 1080 | if (count < mem_mindma) { | ||
| 1081 | memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, count); | ||
| 1082 | goto out; | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | bcount = count; | ||
| 1086 | alignfix = 4 - (off % 4); | ||
| 1087 | if (alignfix != 4) { | ||
| 1088 | if (bcount < alignfix) { | ||
| 1089 | alignfix = bcount; | ||
| 1090 | } | ||
| 1091 | memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, | ||
| 1092 | alignfix); | ||
| 1093 | if (bcount == alignfix) { | ||
| 1094 | goto out; | ||
| 1095 | } | ||
| 1096 | bcount -= alignfix; | ||
| 1097 | off += alignfix; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | while (bcount >= 4) { | ||
| 1101 | retval = mem_dmaread(md, md->lynx->mem_dma_buffer_dma | ||
| 1102 | + count - bcount, bcount, off); | ||
| 1103 | if (retval < 0) return retval; | ||
| 1104 | |||
| 1105 | bcount -= retval; | ||
| 1106 | off += retval; | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | if (bcount) { | ||
| 1110 | memcpy_fromio(md->lynx->mem_dma_buffer + count - bcount, | ||
| 1111 | membase+off, bcount); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | out: | ||
| 1115 | retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count); | ||
| 1116 | up(&md->lynx->mem_dma_mutex); | ||
| 1117 | |||
| 1118 | if (retval) return -EFAULT; | ||
| 1119 | *offset += count; | ||
| 1120 | return count; | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | |||
| 1124 | static ssize_t mem_write(struct file *file, const char *buffer, size_t count, | ||
| 1125 | loff_t *offset) | ||
| 1126 | { | ||
| 1127 | struct memdata *md = (struct memdata *)file->private_data; | ||
| 1128 | |||
| 1129 | if (((*offset) + count) > PCILYNX_MAX_MEMORY+1) { | ||
| 1130 | count = PCILYNX_MAX_MEMORY+1 - *offset; | ||
| 1131 | } | ||
| 1132 | if (count == 0 || *offset > PCILYNX_MAX_MEMORY) { | ||
| 1133 | return -ENOSPC; | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */ | ||
| 1137 | switch (md->type) { | ||
| 1138 | case aux: | ||
| 1139 | if (copy_from_user(md->lynx->aux_port+(*offset), buffer, count)) | ||
| 1140 | return -EFAULT; | ||
| 1141 | break; | ||
| 1142 | case ram: | ||
| 1143 | if (copy_from_user(md->lynx->local_ram+(*offset), buffer, count)) | ||
| 1144 | return -EFAULT; | ||
| 1145 | break; | ||
| 1146 | case rom: | ||
| 1147 | /* the ROM may be writeable */ | ||
| 1148 | if (copy_from_user(md->lynx->local_rom+(*offset), buffer, count)) | ||
| 1149 | return -EFAULT; | ||
| 1150 | break; | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | file->f_pos += count; | ||
| 1154 | return count; | ||
| 1155 | } | ||
| 1156 | #endif /* CONFIG_IEEE1394_PCILYNX_PORTS */ | ||
| 1157 | |||
| 1158 | 838 | ||
| 1159 | /******************************************************** | 839 | /******************************************************** |
| 1160 | * Global stuff (interrupt handler, init/shutdown code) * | 840 | * Global stuff (interrupt handler, init/shutdown code) * |
| @@ -1181,18 +861,6 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id, | |||
| 1181 | reg_write(lynx, LINK_INT_STATUS, linkint); | 861 | reg_write(lynx, LINK_INT_STATUS, linkint); |
| 1182 | reg_write(lynx, PCI_INT_STATUS, intmask); | 862 | reg_write(lynx, PCI_INT_STATUS, intmask); |
| 1183 | 863 | ||
| 1184 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 1185 | if (intmask & PCI_INT_AUX_INT) { | ||
| 1186 | atomic_inc(&lynx->aux_intr_seen); | ||
| 1187 | wake_up_interruptible(&lynx->aux_intr_wait); | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | if (intmask & PCI_INT_DMA_HLT(CHANNEL_LOCALBUS)) { | ||
| 1191 | wake_up_interruptible(&lynx->mem_dma_intr_wait); | ||
| 1192 | } | ||
| 1193 | #endif | ||
| 1194 | |||
| 1195 | |||
| 1196 | if (intmask & PCI_INT_1394) { | 864 | if (intmask & PCI_INT_1394) { |
| 1197 | if (linkint & LINK_INT_PHY_TIMEOUT) { | 865 | if (linkint & LINK_INT_PHY_TIMEOUT) { |
| 1198 | PRINT(KERN_INFO, lynx->id, "PHY timeout occurred"); | 866 | PRINT(KERN_INFO, lynx->id, "PHY timeout occurred"); |
| @@ -1484,15 +1152,9 @@ static void remove_card(struct pci_dev *dev) | |||
| 1484 | pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page, | 1152 | pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page, |
| 1485 | lynx->rcv_page_dma); | 1153 | lynx->rcv_page_dma); |
| 1486 | case have_aux_buf: | 1154 | case have_aux_buf: |
| 1487 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 1488 | pci_free_consistent(lynx->dev, 65536, lynx->mem_dma_buffer, | ||
| 1489 | lynx->mem_dma_buffer_dma); | ||
| 1490 | #endif | ||
| 1491 | case have_pcl_mem: | 1155 | case have_pcl_mem: |
| 1492 | #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
| 1493 | pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem, | 1156 | pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem, |
| 1494 | lynx->pcl_mem_dma); | 1157 | lynx->pcl_mem_dma); |
| 1495 | #endif | ||
| 1496 | case clear: | 1158 | case clear: |
| 1497 | /* do nothing - already freed */ | 1159 | /* do nothing - already freed */ |
| 1498 | ; | 1160 | ; |
| @@ -1524,7 +1186,7 @@ static int __devinit add_card(struct pci_dev *dev, | |||
| 1524 | 1186 | ||
| 1525 | error = -ENXIO; | 1187 | error = -ENXIO; |
| 1526 | 1188 | ||
| 1527 | if (pci_set_dma_mask(dev, 0xffffffff)) | 1189 | if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) |
| 1528 | FAIL("DMA address limits not supported for PCILynx hardware"); | 1190 | FAIL("DMA address limits not supported for PCILynx hardware"); |
| 1529 | if (pci_enable_device(dev)) | 1191 | if (pci_enable_device(dev)) |
| 1530 | FAIL("failed to enable PCILynx hardware"); | 1192 | FAIL("failed to enable PCILynx hardware"); |
| @@ -1546,7 +1208,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
| 1546 | spin_lock_init(&lynx->lock); | 1208 | spin_lock_init(&lynx->lock); |
| 1547 | spin_lock_init(&lynx->phy_reg_lock); | 1209 | spin_lock_init(&lynx->phy_reg_lock); |
| 1548 | 1210 | ||
| 1549 | #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
| 1550 | lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE, | 1211 | lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE, |
| 1551 | &lynx->pcl_mem_dma); | 1212 | &lynx->pcl_mem_dma); |
| 1552 | 1213 | ||
| @@ -1558,16 +1219,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
| 1558 | } else { | 1219 | } else { |
| 1559 | FAIL("failed to allocate PCL memory area"); | 1220 | FAIL("failed to allocate PCL memory area"); |
| 1560 | } | 1221 | } |
| 1561 | #endif | ||
| 1562 | |||
| 1563 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 1564 | lynx->mem_dma_buffer = pci_alloc_consistent(dev, 65536, | ||
| 1565 | &lynx->mem_dma_buffer_dma); | ||
| 1566 | if (lynx->mem_dma_buffer == NULL) { | ||
| 1567 | FAIL("failed to allocate DMA buffer for aux"); | ||
| 1568 | } | ||
| 1569 | lynx->state = have_aux_buf; | ||
| 1570 | #endif | ||
| 1571 | 1222 | ||
| 1572 | lynx->rcv_page = pci_alloc_consistent(dev, PAGE_SIZE, | 1223 | lynx->rcv_page = pci_alloc_consistent(dev, PAGE_SIZE, |
| 1573 | &lynx->rcv_page_dma); | 1224 | &lynx->rcv_page_dma); |
| @@ -1597,13 +1248,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
| 1597 | FAIL("failed to remap registers - card not accessible"); | 1248 | FAIL("failed to remap registers - card not accessible"); |
| 1598 | } | 1249 | } |
| 1599 | 1250 | ||
| 1600 | #ifdef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
| 1601 | if (lynx->local_ram == NULL) { | ||
| 1602 | FAIL("failed to remap local RAM which is required for " | ||
| 1603 | "operation"); | ||
| 1604 | } | ||
| 1605 | #endif | ||
| 1606 | |||
| 1607 | reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); | 1251 | reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); |
| 1608 | /* Fix buggy cards with autoboot pin not tied low: */ | 1252 | /* Fix buggy cards with autoboot pin not tied low: */ |
| 1609 | reg_write(lynx, DMA0_CHAN_CTRL, 0); | 1253 | reg_write(lynx, DMA0_CHAN_CTRL, 0); |
| @@ -1624,13 +1268,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
| 1624 | 1268 | ||
| 1625 | /* alloc_pcl return values are not checked, it is expected that the | 1269 | /* alloc_pcl return values are not checked, it is expected that the |
| 1626 | * provided PCL space is sufficient for the initial allocations */ | 1270 | * provided PCL space is sufficient for the initial allocations */ |
| 1627 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 1628 | if (lynx->aux_port != NULL) { | ||
| 1629 | lynx->dmem_pcl = alloc_pcl(lynx); | ||
| 1630 | aux_setup_pcls(lynx); | ||
| 1631 | sema_init(&lynx->mem_dma_mutex, 1); | ||
| 1632 | } | ||
| 1633 | #endif | ||
| 1634 | lynx->rcv_pcl = alloc_pcl(lynx); | 1271 | lynx->rcv_pcl = alloc_pcl(lynx); |
| 1635 | lynx->rcv_pcl_start = alloc_pcl(lynx); | 1272 | lynx->rcv_pcl_start = alloc_pcl(lynx); |
| 1636 | lynx->async.pcl = alloc_pcl(lynx); | 1273 | lynx->async.pcl = alloc_pcl(lynx); |
| @@ -1647,12 +1284,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
| 1647 | 1284 | ||
| 1648 | reg_write(lynx, PCI_INT_ENABLE, PCI_INT_DMA_ALL); | 1285 | reg_write(lynx, PCI_INT_ENABLE, PCI_INT_DMA_ALL); |
| 1649 | 1286 | ||
| 1650 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 1651 | reg_set_bits(lynx, PCI_INT_ENABLE, PCI_INT_AUX_INT); | ||
| 1652 | init_waitqueue_head(&lynx->mem_dma_intr_wait); | ||
| 1653 | init_waitqueue_head(&lynx->aux_intr_wait); | ||
| 1654 | #endif | ||
| 1655 | |||
| 1656 | tasklet_init(&lynx->iso_rcv.tq, (void (*)(unsigned long))iso_rcv_bh, | 1287 | tasklet_init(&lynx->iso_rcv.tq, (void (*)(unsigned long))iso_rcv_bh, |
| 1657 | (unsigned long)lynx); | 1288 | (unsigned long)lynx); |
| 1658 | 1289 | ||
| @@ -1944,37 +1575,18 @@ static int __init pcilynx_init(void) | |||
| 1944 | { | 1575 | { |
| 1945 | int ret; | 1576 | int ret; |
| 1946 | 1577 | ||
| 1947 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 1948 | if (register_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME, &aux_ops)) { | ||
| 1949 | PRINT_G(KERN_ERR, "allocation of char major number %d failed", | ||
| 1950 | PCILYNX_MAJOR); | ||
| 1951 | return -EBUSY; | ||
| 1952 | } | ||
| 1953 | #endif | ||
| 1954 | |||
| 1955 | ret = pci_register_driver(&lynx_pci_driver); | 1578 | ret = pci_register_driver(&lynx_pci_driver); |
| 1956 | if (ret < 0) { | 1579 | if (ret < 0) { |
| 1957 | PRINT_G(KERN_ERR, "PCI module init failed"); | 1580 | PRINT_G(KERN_ERR, "PCI module init failed"); |
| 1958 | goto free_char_dev; | 1581 | return ret; |
| 1959 | } | 1582 | } |
| 1960 | 1583 | ||
| 1961 | return 0; | 1584 | return 0; |
| 1962 | |||
| 1963 | free_char_dev: | ||
| 1964 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 1965 | unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME); | ||
| 1966 | #endif | ||
| 1967 | |||
| 1968 | return ret; | ||
| 1969 | } | 1585 | } |
| 1970 | 1586 | ||
| 1971 | static void __exit pcilynx_cleanup(void) | 1587 | static void __exit pcilynx_cleanup(void) |
| 1972 | { | 1588 | { |
| 1973 | pci_unregister_driver(&lynx_pci_driver); | 1589 | pci_unregister_driver(&lynx_pci_driver); |
| 1974 | |||
| 1975 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 1976 | unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME); | ||
| 1977 | #endif | ||
| 1978 | } | 1590 | } |
| 1979 | 1591 | ||
| 1980 | 1592 | ||
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 { | |||
| 55 | void __iomem *aux_port; | 55 | void __iomem *aux_port; |
| 56 | quadlet_t bus_info_block[5]; | 56 | quadlet_t bus_info_block[5]; |
| 57 | 57 | ||
| 58 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
| 59 | atomic_t aux_intr_seen; | ||
| 60 | wait_queue_head_t aux_intr_wait; | ||
| 61 | |||
| 62 | void *mem_dma_buffer; | ||
| 63 | dma_addr_t mem_dma_buffer_dma; | ||
| 64 | struct semaphore mem_dma_mutex; | ||
| 65 | wait_queue_head_t mem_dma_intr_wait; | ||
| 66 | #endif | ||
| 67 | |||
| 68 | /* | 58 | /* |
| 69 | * use local RAM of LOCALRAM_SIZE bytes for PCLs, which allows for | 59 | * use local RAM of LOCALRAM_SIZE bytes for PCLs, which allows for |
| 70 | * LOCALRAM_SIZE * 8 PCLs (each sized 128 bytes); | 60 | * LOCALRAM_SIZE * 8 PCLs (each sized 128 bytes); |
| @@ -72,11 +62,9 @@ struct ti_lynx { | |||
| 72 | */ | 62 | */ |
| 73 | u8 pcl_bmap[LOCALRAM_SIZE / 1024]; | 63 | u8 pcl_bmap[LOCALRAM_SIZE / 1024]; |
| 74 | 64 | ||
| 75 | #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
| 76 | /* point to PCLs memory area if needed */ | 65 | /* point to PCLs memory area if needed */ |
| 77 | void *pcl_mem; | 66 | void *pcl_mem; |
| 78 | dma_addr_t pcl_mem_dma; | 67 | dma_addr_t pcl_mem_dma; |
| 79 | #endif | ||
| 80 | 68 | ||
| 81 | /* PCLs for local mem / aux transfers */ | 69 | /* PCLs for local mem / aux transfers */ |
| 82 | pcl_t dmem_pcl; | 70 | pcl_t dmem_pcl; |
| @@ -378,39 +366,6 @@ struct ti_pcl { | |||
| 378 | #define pcloffs(MEMBER) (offsetof(struct ti_pcl, MEMBER)) | 366 | #define pcloffs(MEMBER) (offsetof(struct ti_pcl, MEMBER)) |
| 379 | 367 | ||
| 380 | 368 | ||
| 381 | #ifdef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
| 382 | |||
| 383 | static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid, | ||
| 384 | const struct ti_pcl *pcl) | ||
| 385 | { | ||
| 386 | int i; | ||
| 387 | u32 *in = (u32 *)pcl; | ||
| 388 | u32 *out = (u32 *)(lynx->local_ram + pclid * sizeof(struct ti_pcl)); | ||
| 389 | |||
| 390 | for (i = 0; i < 32; i++, out++, in++) { | ||
| 391 | writel(*in, out); | ||
| 392 | } | ||
| 393 | } | ||
| 394 | |||
| 395 | static inline void get_pcl(const struct ti_lynx *lynx, pcl_t pclid, | ||
| 396 | struct ti_pcl *pcl) | ||
| 397 | { | ||
| 398 | int i; | ||
| 399 | u32 *out = (u32 *)pcl; | ||
| 400 | u32 *in = (u32 *)(lynx->local_ram + pclid * sizeof(struct ti_pcl)); | ||
| 401 | |||
| 402 | for (i = 0; i < 32; i++, out++, in++) { | ||
| 403 | *out = readl(in); | ||
| 404 | } | ||
| 405 | } | ||
| 406 | |||
| 407 | static inline u32 pcl_bus(const struct ti_lynx *lynx, pcl_t pclid) | ||
| 408 | { | ||
| 409 | return pci_resource_start(lynx->dev, 1) + pclid * sizeof(struct ti_pcl); | ||
| 410 | } | ||
| 411 | |||
| 412 | #else /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */ | ||
| 413 | |||
| 414 | static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid, | 369 | static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid, |
| 415 | const struct ti_pcl *pcl) | 370 | const struct ti_pcl *pcl) |
| 416 | { | 371 | { |
| @@ -431,10 +386,8 @@ static inline u32 pcl_bus(const struct ti_lynx *lynx, pcl_t pclid) | |||
| 431 | return lynx->pcl_mem_dma + pclid * sizeof(struct ti_pcl); | 386 | return lynx->pcl_mem_dma + pclid * sizeof(struct ti_pcl); |
| 432 | } | 387 | } |
| 433 | 388 | ||
| 434 | #endif /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */ | ||
| 435 | |||
| 436 | 389 | ||
| 437 | #if defined (CONFIG_IEEE1394_PCILYNX_LOCALRAM) || defined (__BIG_ENDIAN) | 390 | #if defined (__BIG_ENDIAN) |
| 438 | typedef struct ti_pcl pcltmp_t; | 391 | typedef struct ti_pcl pcltmp_t; |
| 439 | 392 | ||
| 440 | static inline struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid, | 393 | static inline struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid, |
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 4bedf7113f40..d68c4658f2fc 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c | |||
| @@ -35,6 +35,11 @@ | |||
| 35 | * | 35 | * |
| 36 | */ | 36 | */ |
| 37 | 37 | ||
| 38 | /* Markus Tavenrath <speedygoo@speedygoo.de> : | ||
| 39 | - fixed checks for valid buffer-numbers in video1394_icotl | ||
| 40 | - changed the ways the dma prg's are used, now it's possible to use | ||
| 41 | even a single dma buffer | ||
| 42 | */ | ||
| 38 | #include <linux/config.h> | 43 | #include <linux/config.h> |
| 39 | #include <linux/kernel.h> | 44 | #include <linux/kernel.h> |
| 40 | #include <linux/list.h> | 45 | #include <linux/list.h> |
| @@ -112,6 +117,7 @@ struct dma_iso_ctx { | |||
| 112 | struct it_dma_prg **it_prg; | 117 | struct it_dma_prg **it_prg; |
| 113 | 118 | ||
| 114 | unsigned int *buffer_status; | 119 | unsigned int *buffer_status; |
| 120 | unsigned int *buffer_prg_assignment; | ||
| 115 | struct timeval *buffer_time; /* time when the buffer was received */ | 121 | struct timeval *buffer_time; /* time when the buffer was received */ |
| 116 | unsigned int *last_used_cmd; /* For ISO Transmit with | 122 | unsigned int *last_used_cmd; /* For ISO Transmit with |
| 117 | variable sized packets only ! */ | 123 | variable sized packets only ! */ |
| @@ -180,23 +186,14 @@ static int free_dma_iso_ctx(struct dma_iso_ctx *d) | |||
| 180 | kfree(d->prg_reg); | 186 | kfree(d->prg_reg); |
| 181 | } | 187 | } |
| 182 | 188 | ||
| 183 | if (d->ir_prg) | 189 | kfree(d->ir_prg); |
| 184 | kfree(d->ir_prg); | 190 | kfree(d->it_prg); |
| 185 | 191 | kfree(d->buffer_status); | |
| 186 | if (d->it_prg) | 192 | kfree(d->buffer_prg_assignment); |
| 187 | kfree(d->it_prg); | 193 | kfree(d->buffer_time); |
| 188 | 194 | kfree(d->last_used_cmd); | |
| 189 | if (d->buffer_status) | 195 | kfree(d->next_buffer); |
| 190 | kfree(d->buffer_status); | ||
| 191 | if (d->buffer_time) | ||
| 192 | kfree(d->buffer_time); | ||
| 193 | if (d->last_used_cmd) | ||
| 194 | kfree(d->last_used_cmd); | ||
| 195 | if (d->next_buffer) | ||
| 196 | kfree(d->next_buffer); | ||
| 197 | |||
| 198 | list_del(&d->link); | 196 | list_del(&d->link); |
| 199 | |||
| 200 | kfree(d); | 197 | kfree(d); |
| 201 | 198 | ||
| 202 | return 0; | 199 | return 0; |
| @@ -230,7 +227,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, | |||
| 230 | /* Init the regions for easy cleanup */ | 227 | /* Init the regions for easy cleanup */ |
| 231 | dma_region_init(&d->dma); | 228 | dma_region_init(&d->dma); |
| 232 | 229 | ||
| 233 | if (dma_region_alloc(&d->dma, d->num_desc * d->buf_size, ohci->dev, | 230 | if (dma_region_alloc(&d->dma, (d->num_desc - 1) * d->buf_size, ohci->dev, |
| 234 | PCI_DMA_BIDIRECTIONAL)) { | 231 | PCI_DMA_BIDIRECTIONAL)) { |
| 235 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma buffer"); | 232 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma buffer"); |
| 236 | free_dma_iso_ctx(d); | 233 | free_dma_iso_ctx(d); |
| @@ -342,6 +339,8 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, | |||
| 342 | 339 | ||
| 343 | d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int), | 340 | d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int), |
| 344 | GFP_KERNEL); | 341 | GFP_KERNEL); |
| 342 | d->buffer_prg_assignment = kmalloc(d->num_desc * sizeof(unsigned int), | ||
| 343 | GFP_KERNEL); | ||
| 345 | d->buffer_time = kmalloc(d->num_desc * sizeof(struct timeval), | 344 | d->buffer_time = kmalloc(d->num_desc * sizeof(struct timeval), |
| 346 | GFP_KERNEL); | 345 | GFP_KERNEL); |
| 347 | d->last_used_cmd = kmalloc(d->num_desc * sizeof(unsigned int), | 346 | 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, | |||
| 354 | free_dma_iso_ctx(d); | 353 | free_dma_iso_ctx(d); |
| 355 | return NULL; | 354 | return NULL; |
| 356 | } | 355 | } |
| 356 | if (d->buffer_prg_assignment == NULL) { | ||
| 357 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_prg_assignment"); | ||
| 358 | free_dma_iso_ctx(d); | ||
| 359 | return NULL; | ||
| 360 | } | ||
| 357 | if (d->buffer_time == NULL) { | 361 | if (d->buffer_time == NULL) { |
| 358 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_time"); | 362 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_time"); |
| 359 | free_dma_iso_ctx(d); | 363 | free_dma_iso_ctx(d); |
| @@ -370,6 +374,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, | |||
| 370 | return NULL; | 374 | return NULL; |
| 371 | } | 375 | } |
| 372 | memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int)); | 376 | memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int)); |
| 377 | memset(d->buffer_prg_assignment, 0, d->num_desc * sizeof(unsigned int)); | ||
| 373 | memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval)); | 378 | memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval)); |
| 374 | memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int)); | 379 | memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int)); |
| 375 | memset(d->next_buffer, -1, d->num_desc * sizeof(int)); | 380 | 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, | |||
| 379 | PRINT(KERN_INFO, ohci->host->id, "Iso %s DMA: %d buffers " | 384 | PRINT(KERN_INFO, ohci->host->id, "Iso %s DMA: %d buffers " |
| 380 | "of size %d allocated for a frame size %d, each with %d prgs", | 385 | "of size %d allocated for a frame size %d, each with %d prgs", |
| 381 | (type == OHCI_ISO_RECEIVE) ? "receive" : "transmit", | 386 | (type == OHCI_ISO_RECEIVE) ? "receive" : "transmit", |
| 382 | d->num_desc, d->buf_size, d->frame_size, d->nb_cmd); | 387 | d->num_desc - 1, d->buf_size, d->frame_size, d->nb_cmd); |
| 383 | 388 | ||
| 384 | return d; | 389 | return d; |
| 385 | } | 390 | } |
| @@ -394,11 +399,36 @@ static void reset_ir_status(struct dma_iso_ctx *d, int n) | |||
| 394 | d->ir_prg[n][i].status = cpu_to_le32(d->left_size); | 399 | d->ir_prg[n][i].status = cpu_to_le32(d->left_size); |
| 395 | } | 400 | } |
| 396 | 401 | ||
| 402 | static void reprogram_dma_ir_prg(struct dma_iso_ctx *d, int n, int buffer, int flags) | ||
| 403 | { | ||
| 404 | struct dma_cmd *ir_prg = d->ir_prg[n]; | ||
| 405 | unsigned long buf = (unsigned long)d->dma.kvirt + buffer * d->buf_size; | ||
| 406 | int i; | ||
| 407 | |||
| 408 | d->buffer_prg_assignment[n] = buffer; | ||
| 409 | |||
| 410 | ir_prg[0].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, buf - | ||
| 411 | (unsigned long)d->dma.kvirt)); | ||
| 412 | ir_prg[1].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, | ||
| 413 | (buf + 4) - (unsigned long)d->dma.kvirt)); | ||
| 414 | |||
| 415 | for (i=2;i<d->nb_cmd-1;i++) { | ||
| 416 | ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, | ||
| 417 | (buf+(i-1)*PAGE_SIZE) - | ||
| 418 | (unsigned long)d->dma.kvirt)); | ||
| 419 | } | ||
| 420 | |||
| 421 | ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | | ||
| 422 | DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size); | ||
| 423 | ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, | ||
| 424 | (buf+(i-1)*PAGE_SIZE) - (unsigned long)d->dma.kvirt)); | ||
| 425 | } | ||
| 426 | |||
| 397 | static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags) | 427 | static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags) |
| 398 | { | 428 | { |
| 399 | struct dma_cmd *ir_prg = d->ir_prg[n]; | 429 | struct dma_cmd *ir_prg = d->ir_prg[n]; |
| 400 | struct dma_prog_region *ir_reg = &d->prg_reg[n]; | 430 | struct dma_prog_region *ir_reg = &d->prg_reg[n]; |
| 401 | unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size; | 431 | unsigned long buf = (unsigned long)d->dma.kvirt; |
| 402 | int i; | 432 | int i; |
| 403 | 433 | ||
| 404 | /* the first descriptor will read only 4 bytes */ | 434 | /* the first descriptor will read only 4 bytes */ |
| @@ -508,7 +538,7 @@ static void wakeup_dma_ir_ctx(unsigned long l) | |||
| 508 | for (i = 0; i < d->num_desc; i++) { | 538 | for (i = 0; i < d->num_desc; i++) { |
| 509 | if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) { | 539 | if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) { |
| 510 | reset_ir_status(d, i); | 540 | reset_ir_status(d, i); |
| 511 | d->buffer_status[i] = VIDEO1394_BUFFER_READY; | 541 | d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY; |
| 512 | do_gettimeofday(&d->buffer_time[i]); | 542 | do_gettimeofday(&d->buffer_time[i]); |
| 513 | } | 543 | } |
| 514 | } | 544 | } |
| @@ -585,7 +615,7 @@ static void wakeup_dma_it_ctx(unsigned long l) | |||
| 585 | int next = d->next_buffer[i]; | 615 | int next = d->next_buffer[i]; |
| 586 | put_timestamp(ohci, d, next); | 616 | put_timestamp(ohci, d, next); |
| 587 | d->it_prg[i][d->last_used_cmd[i]].end.status = 0; | 617 | d->it_prg[i][d->last_used_cmd[i]].end.status = 0; |
| 588 | d->buffer_status[i] = VIDEO1394_BUFFER_READY; | 618 | d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY; |
| 589 | } | 619 | } |
| 590 | } | 620 | } |
| 591 | 621 | ||
| @@ -595,11 +625,25 @@ static void wakeup_dma_it_ctx(unsigned long l) | |||
| 595 | wake_up_interruptible(&d->waitq); | 625 | wake_up_interruptible(&d->waitq); |
| 596 | } | 626 | } |
| 597 | 627 | ||
| 628 | static void reprogram_dma_it_prg(struct dma_iso_ctx *d, int n, int buffer) | ||
| 629 | { | ||
| 630 | struct it_dma_prg *it_prg = d->it_prg[n]; | ||
| 631 | unsigned long buf = (unsigned long)d->dma.kvirt + buffer * d->buf_size; | ||
| 632 | int i; | ||
| 633 | |||
| 634 | d->buffer_prg_assignment[n] = buffer; | ||
| 635 | for (i=0;i<d->nb_cmd;i++) { | ||
| 636 | it_prg[i].end.address = | ||
| 637 | cpu_to_le32(dma_region_offset_to_bus(&d->dma, | ||
| 638 | (buf+i*d->packet_size) - (unsigned long)d->dma.kvirt)); | ||
| 639 | } | ||
| 640 | } | ||
| 641 | |||
| 598 | static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag) | 642 | static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag) |
| 599 | { | 643 | { |
| 600 | struct it_dma_prg *it_prg = d->it_prg[n]; | 644 | struct it_dma_prg *it_prg = d->it_prg[n]; |
| 601 | struct dma_prog_region *it_reg = &d->prg_reg[n]; | 645 | struct dma_prog_region *it_reg = &d->prg_reg[n]; |
| 602 | unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size; | 646 | unsigned long buf = (unsigned long)d->dma.kvirt; |
| 603 | int i; | 647 | int i; |
| 604 | d->last_used_cmd[n] = d->nb_cmd - 1; | 648 | d->last_used_cmd[n] = d->nb_cmd - 1; |
| 605 | for (i=0;i<d->nb_cmd;i++) { | 649 | for (i=0;i<d->nb_cmd;i++) { |
| @@ -796,7 +840,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 796 | 840 | ||
| 797 | if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL) { | 841 | if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL) { |
| 798 | d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE, | 842 | d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE, |
| 799 | v.nb_buffers, v.buf_size, | 843 | v.nb_buffers + 1, v.buf_size, |
| 800 | v.channel, 0); | 844 | v.channel, 0); |
| 801 | 845 | ||
| 802 | if (d == NULL) { | 846 | if (d == NULL) { |
| @@ -817,7 +861,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 817 | } | 861 | } |
| 818 | else { | 862 | else { |
| 819 | d = alloc_dma_iso_ctx(ohci, OHCI_ISO_TRANSMIT, | 863 | d = alloc_dma_iso_ctx(ohci, OHCI_ISO_TRANSMIT, |
| 820 | v.nb_buffers, v.buf_size, | 864 | v.nb_buffers + 1, v.buf_size, |
| 821 | v.channel, v.packet_size); | 865 | v.channel, v.packet_size); |
| 822 | 866 | ||
| 823 | if (d == NULL) { | 867 | if (d == NULL) { |
| @@ -889,6 +933,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 889 | { | 933 | { |
| 890 | struct video1394_wait v; | 934 | struct video1394_wait v; |
| 891 | struct dma_iso_ctx *d; | 935 | struct dma_iso_ctx *d; |
| 936 | int next_prg; | ||
| 892 | 937 | ||
| 893 | if (copy_from_user(&v, argp, sizeof(v))) | 938 | if (copy_from_user(&v, argp, sizeof(v))) |
| 894 | return -EFAULT; | 939 | return -EFAULT; |
| @@ -896,7 +941,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 896 | d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); | 941 | d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); |
| 897 | if (d == NULL) return -EFAULT; | 942 | if (d == NULL) return -EFAULT; |
| 898 | 943 | ||
| 899 | if ((v.buffer<0) || (v.buffer>d->num_desc)) { | 944 | if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) { |
| 900 | PRINT(KERN_ERR, ohci->host->id, | 945 | PRINT(KERN_ERR, ohci->host->id, |
| 901 | "Buffer %d out of range",v.buffer); | 946 | "Buffer %d out of range",v.buffer); |
| 902 | return -EINVAL; | 947 | return -EINVAL; |
| @@ -913,12 +958,14 @@ static int __video1394_ioctl(struct file *file, | |||
| 913 | 958 | ||
| 914 | d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; | 959 | d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; |
| 915 | 960 | ||
| 961 | next_prg = (d->last_buffer + 1) % d->num_desc; | ||
| 916 | if (d->last_buffer>=0) | 962 | if (d->last_buffer>=0) |
| 917 | d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = | 963 | d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = |
| 918 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 964 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0) |
| 919 | & 0xfffffff0) | 0x1); | 965 | & 0xfffffff0) | 0x1); |
| 920 | 966 | ||
| 921 | d->last_buffer = v.buffer; | 967 | d->last_buffer = next_prg; |
| 968 | reprogram_dma_ir_prg(d, d->last_buffer, v.buffer, d->flags); | ||
| 922 | 969 | ||
| 923 | d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = 0; | 970 | d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = 0; |
| 924 | 971 | ||
| @@ -930,7 +977,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 930 | 977 | ||
| 931 | /* Tell the controller where the first program is */ | 978 | /* Tell the controller where the first program is */ |
| 932 | reg_write(ohci, d->cmdPtr, | 979 | reg_write(ohci, d->cmdPtr, |
| 933 | dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x1); | 980 | dma_prog_region_offset_to_bus(&d->prg_reg[d->last_buffer], 0) | 0x1); |
| 934 | 981 | ||
| 935 | /* Run IR context */ | 982 | /* Run IR context */ |
| 936 | reg_write(ohci, d->ctrlSet, 0x8000); | 983 | reg_write(ohci, d->ctrlSet, 0x8000); |
| @@ -951,7 +998,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 951 | { | 998 | { |
| 952 | struct video1394_wait v; | 999 | struct video1394_wait v; |
| 953 | struct dma_iso_ctx *d; | 1000 | struct dma_iso_ctx *d; |
| 954 | int i; | 1001 | int i = 0; |
| 955 | 1002 | ||
| 956 | if (copy_from_user(&v, argp, sizeof(v))) | 1003 | if (copy_from_user(&v, argp, sizeof(v))) |
| 957 | return -EFAULT; | 1004 | return -EFAULT; |
| @@ -959,7 +1006,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 959 | d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); | 1006 | d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); |
| 960 | if (d == NULL) return -EFAULT; | 1007 | if (d == NULL) return -EFAULT; |
| 961 | 1008 | ||
| 962 | if ((v.buffer<0) || (v.buffer>d->num_desc)) { | 1009 | if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) { |
| 963 | PRINT(KERN_ERR, ohci->host->id, | 1010 | PRINT(KERN_ERR, ohci->host->id, |
| 964 | "Buffer %d out of range",v.buffer); | 1011 | "Buffer %d out of range",v.buffer); |
| 965 | return -EINVAL; | 1012 | return -EINVAL; |
| @@ -1005,9 +1052,9 @@ static int __video1394_ioctl(struct file *file, | |||
| 1005 | * Look ahead to see how many more buffers have been received | 1052 | * Look ahead to see how many more buffers have been received |
| 1006 | */ | 1053 | */ |
| 1007 | i=0; | 1054 | i=0; |
| 1008 | while (d->buffer_status[(v.buffer+1)%d->num_desc]== | 1055 | while (d->buffer_status[(v.buffer+1)%(d->num_desc - 1)]== |
| 1009 | VIDEO1394_BUFFER_READY) { | 1056 | VIDEO1394_BUFFER_READY) { |
| 1010 | v.buffer=(v.buffer+1)%d->num_desc; | 1057 | v.buffer=(v.buffer+1)%(d->num_desc - 1); |
| 1011 | i++; | 1058 | i++; |
| 1012 | } | 1059 | } |
| 1013 | spin_unlock_irqrestore(&d->lock, flags); | 1060 | spin_unlock_irqrestore(&d->lock, flags); |
| @@ -1023,6 +1070,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 1023 | struct video1394_wait v; | 1070 | struct video1394_wait v; |
| 1024 | unsigned int *psizes = NULL; | 1071 | unsigned int *psizes = NULL; |
| 1025 | struct dma_iso_ctx *d; | 1072 | struct dma_iso_ctx *d; |
| 1073 | int next_prg; | ||
| 1026 | 1074 | ||
| 1027 | if (copy_from_user(&v, argp, sizeof(v))) | 1075 | if (copy_from_user(&v, argp, sizeof(v))) |
| 1028 | return -EFAULT; | 1076 | return -EFAULT; |
| @@ -1030,7 +1078,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 1030 | d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); | 1078 | d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); |
| 1031 | if (d == NULL) return -EFAULT; | 1079 | if (d == NULL) return -EFAULT; |
| 1032 | 1080 | ||
| 1033 | if ((v.buffer<0) || (v.buffer>d->num_desc)) { | 1081 | if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) { |
| 1034 | PRINT(KERN_ERR, ohci->host->id, | 1082 | PRINT(KERN_ERR, ohci->host->id, |
| 1035 | "Buffer %d out of range",v.buffer); | 1083 | "Buffer %d out of range",v.buffer); |
| 1036 | return -EINVAL; | 1084 | return -EINVAL; |
| @@ -1056,19 +1104,19 @@ static int __video1394_ioctl(struct file *file, | |||
| 1056 | 1104 | ||
| 1057 | spin_lock_irqsave(&d->lock,flags); | 1105 | spin_lock_irqsave(&d->lock,flags); |
| 1058 | 1106 | ||
| 1107 | // last_buffer is last_prg | ||
| 1108 | next_prg = (d->last_buffer + 1) % d->num_desc; | ||
| 1059 | if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) { | 1109 | if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) { |
| 1060 | PRINT(KERN_ERR, ohci->host->id, | 1110 | PRINT(KERN_ERR, ohci->host->id, |
| 1061 | "Buffer %d is already used",v.buffer); | 1111 | "Buffer %d is already used",v.buffer); |
| 1062 | spin_unlock_irqrestore(&d->lock,flags); | 1112 | spin_unlock_irqrestore(&d->lock,flags); |
| 1063 | if (psizes) | 1113 | kfree(psizes); |
| 1064 | kfree(psizes); | ||
| 1065 | return -EBUSY; | 1114 | return -EBUSY; |
| 1066 | } | 1115 | } |
| 1067 | 1116 | ||
| 1068 | if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { | 1117 | if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { |
| 1069 | initialize_dma_it_prg_var_packet_queue( | 1118 | initialize_dma_it_prg_var_packet_queue( |
| 1070 | d, v.buffer, psizes, | 1119 | d, next_prg, psizes, ohci); |
| 1071 | ohci); | ||
| 1072 | } | 1120 | } |
| 1073 | 1121 | ||
| 1074 | d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; | 1122 | d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; |
| @@ -1076,16 +1124,17 @@ static int __video1394_ioctl(struct file *file, | |||
| 1076 | if (d->last_buffer >= 0) { | 1124 | if (d->last_buffer >= 0) { |
| 1077 | d->it_prg[d->last_buffer] | 1125 | d->it_prg[d->last_buffer] |
| 1078 | [ d->last_used_cmd[d->last_buffer] ].end.branchAddress = | 1126 | [ d->last_used_cmd[d->last_buffer] ].end.branchAddress = |
| 1079 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], | 1127 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], |
| 1080 | 0) & 0xfffffff0) | 0x3); | 1128 | 0) & 0xfffffff0) | 0x3); |
| 1081 | 1129 | ||
| 1082 | d->it_prg[d->last_buffer] | 1130 | d->it_prg[d->last_buffer] |
| 1083 | [ d->last_used_cmd[d->last_buffer] ].begin.branchAddress = | 1131 | [ d->last_used_cmd[d->last_buffer] ].begin.branchAddress = |
| 1084 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], | 1132 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], |
| 1085 | 0) & 0xfffffff0) | 0x3); | 1133 | 0) & 0xfffffff0) | 0x3); |
| 1086 | d->next_buffer[d->last_buffer] = v.buffer; | 1134 | d->next_buffer[d->last_buffer] = (v.buffer + 1) % (d->num_desc - 1); |
| 1087 | } | 1135 | } |
| 1088 | d->last_buffer = v.buffer; | 1136 | d->last_buffer = next_prg; |
| 1137 | reprogram_dma_it_prg(d, d->last_buffer, v.buffer); | ||
| 1089 | d->next_buffer[d->last_buffer] = -1; | 1138 | d->next_buffer[d->last_buffer] = -1; |
| 1090 | 1139 | ||
| 1091 | d->it_prg[d->last_buffer][d->last_used_cmd[d->last_buffer]].end.branchAddress = 0; | 1140 | 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, | |||
| 1100 | 1149 | ||
| 1101 | /* Tell the controller where the first program is */ | 1150 | /* Tell the controller where the first program is */ |
| 1102 | reg_write(ohci, d->cmdPtr, | 1151 | reg_write(ohci, d->cmdPtr, |
| 1103 | dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x3); | 1152 | dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0) | 0x3); |
| 1104 | 1153 | ||
| 1105 | /* Run IT context */ | 1154 | /* Run IT context */ |
| 1106 | reg_write(ohci, d->ctrlSet, 0x8000); | 1155 | reg_write(ohci, d->ctrlSet, 0x8000); |
| @@ -1116,9 +1165,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 1116 | } | 1165 | } |
| 1117 | } | 1166 | } |
| 1118 | 1167 | ||
| 1119 | if (psizes) | 1168 | kfree(psizes); |
| 1120 | kfree(psizes); | ||
| 1121 | |||
| 1122 | return 0; | 1169 | return 0; |
| 1123 | 1170 | ||
| 1124 | } | 1171 | } |
| @@ -1133,7 +1180,7 @@ static int __video1394_ioctl(struct file *file, | |||
| 1133 | d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); | 1180 | d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); |
| 1134 | if (d == NULL) return -EFAULT; | 1181 | if (d == NULL) return -EFAULT; |
| 1135 | 1182 | ||
| 1136 | if ((v.buffer<0) || (v.buffer>d->num_desc)) { | 1183 | if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) { |
| 1137 | PRINT(KERN_ERR, ohci->host->id, | 1184 | PRINT(KERN_ERR, ohci->host->id, |
| 1138 | "Buffer %d out of range",v.buffer); | 1185 | "Buffer %d out of range",v.buffer); |
| 1139 | return -EINVAL; | 1186 | return -EINVAL; |
