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; |