diff options
Diffstat (limited to 'drivers/ieee1394/raw1394.c')
-rw-r--r-- | drivers/ieee1394/raw1394.c | 364 |
1 files changed, 152 insertions, 212 deletions
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index f1d05eeb9f51..336e5ff4cfcf 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c | |||
@@ -98,21 +98,6 @@ static struct hpsb_address_ops arm_ops = { | |||
98 | 98 | ||
99 | static void queue_complete_cb(struct pending_request *req); | 99 | static void queue_complete_cb(struct pending_request *req); |
100 | 100 | ||
101 | #include <asm/current.h> | ||
102 | static void print_old_iso_deprecation(void) | ||
103 | { | ||
104 | static pid_t p; | ||
105 | |||
106 | if (p == current->pid) | ||
107 | return; | ||
108 | p = current->pid; | ||
109 | printk(KERN_WARNING "raw1394: WARNING - Program \"%s\" uses unsupported" | ||
110 | " isochronous request types which will be removed in a next" | ||
111 | " kernel release\n", current->comm); | ||
112 | printk(KERN_WARNING "raw1394: Update your software to use libraw1394's" | ||
113 | " newer interface\n"); | ||
114 | } | ||
115 | |||
116 | static struct pending_request *__alloc_pending_request(gfp_t flags) | 101 | static struct pending_request *__alloc_pending_request(gfp_t flags) |
117 | { | 102 | { |
118 | struct pending_request *req; | 103 | struct pending_request *req; |
@@ -297,67 +282,6 @@ static void host_reset(struct hpsb_host *host) | |||
297 | spin_unlock_irqrestore(&host_info_lock, flags); | 282 | spin_unlock_irqrestore(&host_info_lock, flags); |
298 | } | 283 | } |
299 | 284 | ||
300 | static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data, | ||
301 | size_t length) | ||
302 | { | ||
303 | unsigned long flags; | ||
304 | struct host_info *hi; | ||
305 | struct file_info *fi; | ||
306 | struct pending_request *req, *req_next; | ||
307 | struct iso_block_store *ibs = NULL; | ||
308 | LIST_HEAD(reqs); | ||
309 | |||
310 | if ((atomic_read(&iso_buffer_size) + length) > iso_buffer_max) { | ||
311 | HPSB_INFO("dropped iso packet"); | ||
312 | return; | ||
313 | } | ||
314 | |||
315 | spin_lock_irqsave(&host_info_lock, flags); | ||
316 | hi = find_host_info(host); | ||
317 | |||
318 | if (hi != NULL) { | ||
319 | list_for_each_entry(fi, &hi->file_info_list, list) { | ||
320 | if (!(fi->listen_channels & (1ULL << channel))) | ||
321 | continue; | ||
322 | |||
323 | req = __alloc_pending_request(GFP_ATOMIC); | ||
324 | if (!req) | ||
325 | break; | ||
326 | |||
327 | if (!ibs) { | ||
328 | ibs = kmalloc(sizeof(*ibs) + length, | ||
329 | GFP_ATOMIC); | ||
330 | if (!ibs) { | ||
331 | kfree(req); | ||
332 | break; | ||
333 | } | ||
334 | |||
335 | atomic_add(length, &iso_buffer_size); | ||
336 | atomic_set(&ibs->refcount, 0); | ||
337 | ibs->data_size = length; | ||
338 | memcpy(ibs->data, data, length); | ||
339 | } | ||
340 | |||
341 | atomic_inc(&ibs->refcount); | ||
342 | |||
343 | req->file_info = fi; | ||
344 | req->ibs = ibs; | ||
345 | req->data = ibs->data; | ||
346 | req->req.type = RAW1394_REQ_ISO_RECEIVE; | ||
347 | req->req.generation = get_hpsb_generation(host); | ||
348 | req->req.misc = 0; | ||
349 | req->req.recvb = ptr2int(fi->iso_buffer); | ||
350 | req->req.length = min(length, fi->iso_buffer_length); | ||
351 | |||
352 | list_add_tail(&req->list, &reqs); | ||
353 | } | ||
354 | } | ||
355 | spin_unlock_irqrestore(&host_info_lock, flags); | ||
356 | |||
357 | list_for_each_entry_safe(req, req_next, &reqs, list) | ||
358 | queue_complete_req(req); | ||
359 | } | ||
360 | |||
361 | static void fcp_request(struct hpsb_host *host, int nodeid, int direction, | 285 | static void fcp_request(struct hpsb_host *host, int nodeid, int direction, |
362 | int cts, u8 * data, size_t length) | 286 | int cts, u8 * data, size_t length) |
363 | { | 287 | { |
@@ -434,7 +358,11 @@ struct compat_raw1394_req { | |||
434 | 358 | ||
435 | __u64 sendb; | 359 | __u64 sendb; |
436 | __u64 recvb; | 360 | __u64 recvb; |
437 | } __attribute__((packed)); | 361 | } |
362 | #if defined(CONFIG_X86_64) || defined(CONFIG_IA64) | ||
363 | __attribute__((packed)) | ||
364 | #endif | ||
365 | ; | ||
438 | 366 | ||
439 | static const char __user *raw1394_compat_write(const char __user *buf) | 367 | static const char __user *raw1394_compat_write(const char __user *buf) |
440 | { | 368 | { |
@@ -459,7 +387,7 @@ static const char __user *raw1394_compat_write(const char __user *buf) | |||
459 | static int | 387 | static int |
460 | raw1394_compat_read(const char __user *buf, struct raw1394_request *r) | 388 | raw1394_compat_read(const char __user *buf, struct raw1394_request *r) |
461 | { | 389 | { |
462 | struct compat_raw1394_req __user *cr = (typeof(cr)) r; | 390 | struct compat_raw1394_req __user *cr = (typeof(cr)) buf; |
463 | if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) || | 391 | if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) || |
464 | P(type) || | 392 | P(type) || |
465 | P(error) || | 393 | P(error) || |
@@ -587,7 +515,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req) | |||
587 | 515 | ||
588 | req->req.length = 0; | 516 | req->req.length = 0; |
589 | queue_complete_req(req); | 517 | queue_complete_req(req); |
590 | return sizeof(struct raw1394_request); | 518 | return 0; |
591 | } | 519 | } |
592 | 520 | ||
593 | static int state_initialized(struct file_info *fi, struct pending_request *req) | 521 | static int state_initialized(struct file_info *fi, struct pending_request *req) |
@@ -601,7 +529,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) | |||
601 | req->req.generation = atomic_read(&internal_generation); | 529 | req->req.generation = atomic_read(&internal_generation); |
602 | req->req.length = 0; | 530 | req->req.length = 0; |
603 | queue_complete_req(req); | 531 | queue_complete_req(req); |
604 | return sizeof(struct raw1394_request); | 532 | return 0; |
605 | } | 533 | } |
606 | 534 | ||
607 | switch (req->req.type) { | 535 | switch (req->req.type) { |
@@ -673,44 +601,7 @@ out_set_card: | |||
673 | } | 601 | } |
674 | 602 | ||
675 | queue_complete_req(req); | 603 | queue_complete_req(req); |
676 | return sizeof(struct raw1394_request); | 604 | return 0; |
677 | } | ||
678 | |||
679 | static void handle_iso_listen(struct file_info *fi, struct pending_request *req) | ||
680 | { | ||
681 | int channel = req->req.misc; | ||
682 | |||
683 | if ((channel > 63) || (channel < -64)) { | ||
684 | req->req.error = RAW1394_ERROR_INVALID_ARG; | ||
685 | } else if (channel >= 0) { | ||
686 | /* allocate channel req.misc */ | ||
687 | if (fi->listen_channels & (1ULL << channel)) { | ||
688 | req->req.error = RAW1394_ERROR_ALREADY; | ||
689 | } else { | ||
690 | if (hpsb_listen_channel | ||
691 | (&raw1394_highlevel, fi->host, channel)) { | ||
692 | req->req.error = RAW1394_ERROR_ALREADY; | ||
693 | } else { | ||
694 | fi->listen_channels |= 1ULL << channel; | ||
695 | fi->iso_buffer = int2ptr(req->req.recvb); | ||
696 | fi->iso_buffer_length = req->req.length; | ||
697 | } | ||
698 | } | ||
699 | } else { | ||
700 | /* deallocate channel (one's complement neg) req.misc */ | ||
701 | channel = ~channel; | ||
702 | |||
703 | if (fi->listen_channels & (1ULL << channel)) { | ||
704 | hpsb_unlisten_channel(&raw1394_highlevel, fi->host, | ||
705 | channel); | ||
706 | fi->listen_channels &= ~(1ULL << channel); | ||
707 | } else { | ||
708 | req->req.error = RAW1394_ERROR_INVALID_ARG; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | req->req.length = 0; | ||
713 | queue_complete_req(req); | ||
714 | } | 605 | } |
715 | 606 | ||
716 | static void handle_fcp_listen(struct file_info *fi, struct pending_request *req) | 607 | static void handle_fcp_listen(struct file_info *fi, struct pending_request *req) |
@@ -865,7 +756,7 @@ static int handle_async_request(struct file_info *fi, | |||
865 | if (req->req.error) { | 756 | if (req->req.error) { |
866 | req->req.length = 0; | 757 | req->req.length = 0; |
867 | queue_complete_req(req); | 758 | queue_complete_req(req); |
868 | return sizeof(struct raw1394_request); | 759 | return 0; |
869 | } | 760 | } |
870 | 761 | ||
871 | hpsb_set_packet_complete_task(packet, | 762 | hpsb_set_packet_complete_task(packet, |
@@ -883,51 +774,7 @@ static int handle_async_request(struct file_info *fi, | |||
883 | hpsb_free_tlabel(packet); | 774 | hpsb_free_tlabel(packet); |
884 | queue_complete_req(req); | 775 | queue_complete_req(req); |
885 | } | 776 | } |
886 | return sizeof(struct raw1394_request); | 777 | return 0; |
887 | } | ||
888 | |||
889 | static int handle_iso_send(struct file_info *fi, struct pending_request *req, | ||
890 | int channel) | ||
891 | { | ||
892 | unsigned long flags; | ||
893 | struct hpsb_packet *packet; | ||
894 | |||
895 | packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f, | ||
896 | (req->req.misc >> 16) & 0x3, | ||
897 | req->req.misc & 0xf); | ||
898 | if (!packet) | ||
899 | return -ENOMEM; | ||
900 | |||
901 | packet->speed_code = req->req.address & 0x3; | ||
902 | |||
903 | req->packet = packet; | ||
904 | |||
905 | if (copy_from_user(packet->data, int2ptr(req->req.sendb), | ||
906 | req->req.length)) { | ||
907 | req->req.error = RAW1394_ERROR_MEMFAULT; | ||
908 | req->req.length = 0; | ||
909 | queue_complete_req(req); | ||
910 | return sizeof(struct raw1394_request); | ||
911 | } | ||
912 | |||
913 | req->req.length = 0; | ||
914 | hpsb_set_packet_complete_task(packet, | ||
915 | (void (*)(void *))queue_complete_req, | ||
916 | req); | ||
917 | |||
918 | spin_lock_irqsave(&fi->reqlists_lock, flags); | ||
919 | list_add_tail(&req->list, &fi->req_pending); | ||
920 | spin_unlock_irqrestore(&fi->reqlists_lock, flags); | ||
921 | |||
922 | /* Update the generation of the packet just before sending. */ | ||
923 | packet->generation = req->req.generation; | ||
924 | |||
925 | if (hpsb_send_packet(packet) < 0) { | ||
926 | req->req.error = RAW1394_ERROR_SEND_ERROR; | ||
927 | queue_complete_req(req); | ||
928 | } | ||
929 | |||
930 | return sizeof(struct raw1394_request); | ||
931 | } | 778 | } |
932 | 779 | ||
933 | static int handle_async_send(struct file_info *fi, struct pending_request *req) | 780 | static int handle_async_send(struct file_info *fi, struct pending_request *req) |
@@ -943,7 +790,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) | |||
943 | req->req.error = RAW1394_ERROR_INVALID_ARG; | 790 | req->req.error = RAW1394_ERROR_INVALID_ARG; |
944 | req->req.length = 0; | 791 | req->req.length = 0; |
945 | queue_complete_req(req); | 792 | queue_complete_req(req); |
946 | return sizeof(struct raw1394_request); | 793 | return 0; |
947 | } | 794 | } |
948 | 795 | ||
949 | data_size = req->req.length - header_length; | 796 | data_size = req->req.length - header_length; |
@@ -957,7 +804,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) | |||
957 | req->req.error = RAW1394_ERROR_MEMFAULT; | 804 | req->req.error = RAW1394_ERROR_MEMFAULT; |
958 | req->req.length = 0; | 805 | req->req.length = 0; |
959 | queue_complete_req(req); | 806 | queue_complete_req(req); |
960 | return sizeof(struct raw1394_request); | 807 | return 0; |
961 | } | 808 | } |
962 | 809 | ||
963 | if (copy_from_user | 810 | if (copy_from_user |
@@ -966,7 +813,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) | |||
966 | req->req.error = RAW1394_ERROR_MEMFAULT; | 813 | req->req.error = RAW1394_ERROR_MEMFAULT; |
967 | req->req.length = 0; | 814 | req->req.length = 0; |
968 | queue_complete_req(req); | 815 | queue_complete_req(req); |
969 | return sizeof(struct raw1394_request); | 816 | return 0; |
970 | } | 817 | } |
971 | 818 | ||
972 | packet->type = hpsb_async; | 819 | packet->type = hpsb_async; |
@@ -994,7 +841,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) | |||
994 | queue_complete_req(req); | 841 | queue_complete_req(req); |
995 | } | 842 | } |
996 | 843 | ||
997 | return sizeof(struct raw1394_request); | 844 | return 0; |
998 | } | 845 | } |
999 | 846 | ||
1000 | static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, | 847 | static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, |
@@ -1869,7 +1716,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) | |||
1869 | spin_lock_irqsave(&host_info_lock, flags); | 1716 | spin_lock_irqsave(&host_info_lock, flags); |
1870 | list_add_tail(&addr->addr_list, &fi->addr_list); | 1717 | list_add_tail(&addr->addr_list, &fi->addr_list); |
1871 | spin_unlock_irqrestore(&host_info_lock, flags); | 1718 | spin_unlock_irqrestore(&host_info_lock, flags); |
1872 | return sizeof(struct raw1394_request); | 1719 | return 0; |
1873 | } | 1720 | } |
1874 | retval = | 1721 | retval = |
1875 | hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, | 1722 | hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, |
@@ -1887,7 +1734,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) | |||
1887 | return (-EALREADY); | 1734 | return (-EALREADY); |
1888 | } | 1735 | } |
1889 | free_pending_request(req); /* immediate success or fail */ | 1736 | free_pending_request(req); /* immediate success or fail */ |
1890 | return sizeof(struct raw1394_request); | 1737 | return 0; |
1891 | } | 1738 | } |
1892 | 1739 | ||
1893 | static int arm_unregister(struct file_info *fi, struct pending_request *req) | 1740 | static int arm_unregister(struct file_info *fi, struct pending_request *req) |
@@ -1955,7 +1802,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) | |||
1955 | vfree(addr->addr_space_buffer); | 1802 | vfree(addr->addr_space_buffer); |
1956 | kfree(addr); | 1803 | kfree(addr); |
1957 | free_pending_request(req); /* immediate success or fail */ | 1804 | free_pending_request(req); /* immediate success or fail */ |
1958 | return sizeof(struct raw1394_request); | 1805 | return 0; |
1959 | } | 1806 | } |
1960 | retval = | 1807 | retval = |
1961 | hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, | 1808 | hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, |
@@ -1971,7 +1818,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) | |||
1971 | vfree(addr->addr_space_buffer); | 1818 | vfree(addr->addr_space_buffer); |
1972 | kfree(addr); | 1819 | kfree(addr); |
1973 | free_pending_request(req); /* immediate success or fail */ | 1820 | free_pending_request(req); /* immediate success or fail */ |
1974 | return sizeof(struct raw1394_request); | 1821 | return 0; |
1975 | } | 1822 | } |
1976 | 1823 | ||
1977 | /* Copy data from ARM buffer(s) to user buffer. */ | 1824 | /* Copy data from ARM buffer(s) to user buffer. */ |
@@ -2013,7 +1860,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req) | |||
2013 | * queue no response, and therefore nobody | 1860 | * queue no response, and therefore nobody |
2014 | * will free it. */ | 1861 | * will free it. */ |
2015 | free_pending_request(req); | 1862 | free_pending_request(req); |
2016 | return sizeof(struct raw1394_request); | 1863 | return 0; |
2017 | } else { | 1864 | } else { |
2018 | DBGMSG("arm_get_buf request exceeded mapping"); | 1865 | DBGMSG("arm_get_buf request exceeded mapping"); |
2019 | spin_unlock_irqrestore(&host_info_lock, flags); | 1866 | spin_unlock_irqrestore(&host_info_lock, flags); |
@@ -2065,7 +1912,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req) | |||
2065 | * queue no response, and therefore nobody | 1912 | * queue no response, and therefore nobody |
2066 | * will free it. */ | 1913 | * will free it. */ |
2067 | free_pending_request(req); | 1914 | free_pending_request(req); |
2068 | return sizeof(struct raw1394_request); | 1915 | return 0; |
2069 | } else { | 1916 | } else { |
2070 | DBGMSG("arm_set_buf request exceeded mapping"); | 1917 | DBGMSG("arm_set_buf request exceeded mapping"); |
2071 | spin_unlock_irqrestore(&host_info_lock, flags); | 1918 | spin_unlock_irqrestore(&host_info_lock, flags); |
@@ -2086,7 +1933,7 @@ static int reset_notification(struct file_info *fi, struct pending_request *req) | |||
2086 | (req->req.misc == RAW1394_NOTIFY_ON)) { | 1933 | (req->req.misc == RAW1394_NOTIFY_ON)) { |
2087 | fi->notification = (u8) req->req.misc; | 1934 | fi->notification = (u8) req->req.misc; |
2088 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ | 1935 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ |
2089 | return sizeof(struct raw1394_request); | 1936 | return 0; |
2090 | } | 1937 | } |
2091 | /* error EINVAL (22) invalid argument */ | 1938 | /* error EINVAL (22) invalid argument */ |
2092 | return (-EINVAL); | 1939 | return (-EINVAL); |
@@ -2119,12 +1966,12 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req) | |||
2119 | req->req.length = 0; | 1966 | req->req.length = 0; |
2120 | queue_complete_req(req); | 1967 | queue_complete_req(req); |
2121 | } | 1968 | } |
2122 | return sizeof(struct raw1394_request); | 1969 | return 0; |
2123 | } | 1970 | } |
2124 | 1971 | ||
2125 | static int get_config_rom(struct file_info *fi, struct pending_request *req) | 1972 | static int get_config_rom(struct file_info *fi, struct pending_request *req) |
2126 | { | 1973 | { |
2127 | int ret = sizeof(struct raw1394_request); | 1974 | int ret = 0; |
2128 | quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); | 1975 | quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); |
2129 | int status; | 1976 | int status; |
2130 | 1977 | ||
@@ -2154,7 +2001,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req) | |||
2154 | 2001 | ||
2155 | static int update_config_rom(struct file_info *fi, struct pending_request *req) | 2002 | static int update_config_rom(struct file_info *fi, struct pending_request *req) |
2156 | { | 2003 | { |
2157 | int ret = sizeof(struct raw1394_request); | 2004 | int ret = 0; |
2158 | quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); | 2005 | quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); |
2159 | if (!data) | 2006 | if (!data) |
2160 | return -ENOMEM; | 2007 | return -ENOMEM; |
@@ -2221,7 +2068,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) | |||
2221 | 2068 | ||
2222 | hpsb_update_config_rom_image(fi->host); | 2069 | hpsb_update_config_rom_image(fi->host); |
2223 | free_pending_request(req); | 2070 | free_pending_request(req); |
2224 | return sizeof(struct raw1394_request); | 2071 | return 0; |
2225 | } | 2072 | } |
2226 | } | 2073 | } |
2227 | 2074 | ||
@@ -2286,7 +2133,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) | |||
2286 | /* we have to free the request, because we queue no response, | 2133 | /* we have to free the request, because we queue no response, |
2287 | * and therefore nobody will free it */ | 2134 | * and therefore nobody will free it */ |
2288 | free_pending_request(req); | 2135 | free_pending_request(req); |
2289 | return sizeof(struct raw1394_request); | 2136 | return 0; |
2290 | } else { | 2137 | } else { |
2291 | for (dentry = | 2138 | for (dentry = |
2292 | fi->csr1212_dirs[dr]->value.directory.dentries_head; | 2139 | fi->csr1212_dirs[dr]->value.directory.dentries_head; |
@@ -2311,11 +2158,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) | |||
2311 | 2158 | ||
2312 | case RAW1394_REQ_ECHO: | 2159 | case RAW1394_REQ_ECHO: |
2313 | queue_complete_req(req); | 2160 | queue_complete_req(req); |
2314 | return sizeof(struct raw1394_request); | 2161 | return 0; |
2315 | |||
2316 | case RAW1394_REQ_ISO_SEND: | ||
2317 | print_old_iso_deprecation(); | ||
2318 | return handle_iso_send(fi, req, node); | ||
2319 | 2162 | ||
2320 | case RAW1394_REQ_ARM_REGISTER: | 2163 | case RAW1394_REQ_ARM_REGISTER: |
2321 | return arm_register(fi, req); | 2164 | return arm_register(fi, req); |
@@ -2332,27 +2175,30 @@ static int state_connected(struct file_info *fi, struct pending_request *req) | |||
2332 | case RAW1394_REQ_RESET_NOTIFY: | 2175 | case RAW1394_REQ_RESET_NOTIFY: |
2333 | return reset_notification(fi, req); | 2176 | return reset_notification(fi, req); |
2334 | 2177 | ||
2178 | case RAW1394_REQ_ISO_SEND: | ||
2335 | case RAW1394_REQ_ISO_LISTEN: | 2179 | case RAW1394_REQ_ISO_LISTEN: |
2336 | print_old_iso_deprecation(); | 2180 | printk(KERN_DEBUG "raw1394: old iso ABI has been removed\n"); |
2337 | handle_iso_listen(fi, req); | 2181 | req->req.error = RAW1394_ERROR_COMPAT; |
2338 | return sizeof(struct raw1394_request); | 2182 | req->req.misc = RAW1394_KERNELAPI_VERSION; |
2183 | queue_complete_req(req); | ||
2184 | return 0; | ||
2339 | 2185 | ||
2340 | case RAW1394_REQ_FCP_LISTEN: | 2186 | case RAW1394_REQ_FCP_LISTEN: |
2341 | handle_fcp_listen(fi, req); | 2187 | handle_fcp_listen(fi, req); |
2342 | return sizeof(struct raw1394_request); | 2188 | return 0; |
2343 | 2189 | ||
2344 | case RAW1394_REQ_RESET_BUS: | 2190 | case RAW1394_REQ_RESET_BUS: |
2345 | if (req->req.misc == RAW1394_LONG_RESET) { | 2191 | if (req->req.misc == RAW1394_LONG_RESET) { |
2346 | DBGMSG("busreset called (type: LONG)"); | 2192 | DBGMSG("busreset called (type: LONG)"); |
2347 | hpsb_reset_bus(fi->host, LONG_RESET); | 2193 | hpsb_reset_bus(fi->host, LONG_RESET); |
2348 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ | 2194 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ |
2349 | return sizeof(struct raw1394_request); | 2195 | return 0; |
2350 | } | 2196 | } |
2351 | if (req->req.misc == RAW1394_SHORT_RESET) { | 2197 | if (req->req.misc == RAW1394_SHORT_RESET) { |
2352 | DBGMSG("busreset called (type: SHORT)"); | 2198 | DBGMSG("busreset called (type: SHORT)"); |
2353 | hpsb_reset_bus(fi->host, SHORT_RESET); | 2199 | hpsb_reset_bus(fi->host, SHORT_RESET); |
2354 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ | 2200 | free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ |
2355 | return sizeof(struct raw1394_request); | 2201 | return 0; |
2356 | } | 2202 | } |
2357 | /* error EINVAL (22) invalid argument */ | 2203 | /* error EINVAL (22) invalid argument */ |
2358 | return (-EINVAL); | 2204 | return (-EINVAL); |
@@ -2371,7 +2217,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) | |||
2371 | req->req.generation = get_hpsb_generation(fi->host); | 2217 | req->req.generation = get_hpsb_generation(fi->host); |
2372 | req->req.length = 0; | 2218 | req->req.length = 0; |
2373 | queue_complete_req(req); | 2219 | queue_complete_req(req); |
2374 | return sizeof(struct raw1394_request); | 2220 | return 0; |
2375 | } | 2221 | } |
2376 | 2222 | ||
2377 | switch (req->req.type) { | 2223 | switch (req->req.type) { |
@@ -2384,7 +2230,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) | |||
2384 | if (req->req.length == 0) { | 2230 | if (req->req.length == 0) { |
2385 | req->req.error = RAW1394_ERROR_INVALID_ARG; | 2231 | req->req.error = RAW1394_ERROR_INVALID_ARG; |
2386 | queue_complete_req(req); | 2232 | queue_complete_req(req); |
2387 | return sizeof(struct raw1394_request); | 2233 | return 0; |
2388 | } | 2234 | } |
2389 | 2235 | ||
2390 | return handle_async_request(fi, req, node); | 2236 | return handle_async_request(fi, req, node); |
@@ -2395,7 +2241,7 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, | |||
2395 | { | 2241 | { |
2396 | struct file_info *fi = (struct file_info *)file->private_data; | 2242 | struct file_info *fi = (struct file_info *)file->private_data; |
2397 | struct pending_request *req; | 2243 | struct pending_request *req; |
2398 | ssize_t retval = 0; | 2244 | ssize_t retval = -EBADFD; |
2399 | 2245 | ||
2400 | #ifdef CONFIG_COMPAT | 2246 | #ifdef CONFIG_COMPAT |
2401 | if (count == sizeof(struct compat_raw1394_req) && | 2247 | if (count == sizeof(struct compat_raw1394_req) && |
@@ -2437,6 +2283,9 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, | |||
2437 | 2283 | ||
2438 | if (retval < 0) { | 2284 | if (retval < 0) { |
2439 | free_pending_request(req); | 2285 | free_pending_request(req); |
2286 | } else { | ||
2287 | BUG_ON(retval); | ||
2288 | retval = count; | ||
2440 | } | 2289 | } |
2441 | 2290 | ||
2442 | return retval; | 2291 | return retval; |
@@ -2802,6 +2651,103 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, | |||
2802 | return -EINVAL; | 2651 | return -EINVAL; |
2803 | } | 2652 | } |
2804 | 2653 | ||
2654 | #ifdef CONFIG_COMPAT | ||
2655 | struct raw1394_iso_packets32 { | ||
2656 | __u32 n_packets; | ||
2657 | compat_uptr_t infos; | ||
2658 | } __attribute__((packed)); | ||
2659 | |||
2660 | struct raw1394_cycle_timer32 { | ||
2661 | __u32 cycle_timer; | ||
2662 | __u64 local_time; | ||
2663 | } | ||
2664 | #if defined(CONFIG_X86_64) || defined(CONFIG_IA64) | ||
2665 | __attribute__((packed)) | ||
2666 | #endif | ||
2667 | ; | ||
2668 | |||
2669 | #define RAW1394_IOC_ISO_RECV_PACKETS32 \ | ||
2670 | _IOW ('#', 0x25, struct raw1394_iso_packets32) | ||
2671 | #define RAW1394_IOC_ISO_XMIT_PACKETS32 \ | ||
2672 | _IOW ('#', 0x27, struct raw1394_iso_packets32) | ||
2673 | #define RAW1394_IOC_GET_CYCLE_TIMER32 \ | ||
2674 | _IOR ('#', 0x30, struct raw1394_cycle_timer32) | ||
2675 | |||
2676 | static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd, | ||
2677 | struct raw1394_iso_packets32 __user *arg) | ||
2678 | { | ||
2679 | compat_uptr_t infos32; | ||
2680 | void *infos; | ||
2681 | long err = -EFAULT; | ||
2682 | struct raw1394_iso_packets __user *dst = compat_alloc_user_space(sizeof(struct raw1394_iso_packets)); | ||
2683 | |||
2684 | if (!copy_in_user(&dst->n_packets, &arg->n_packets, sizeof arg->n_packets) && | ||
2685 | !copy_from_user(&infos32, &arg->infos, sizeof infos32)) { | ||
2686 | infos = compat_ptr(infos32); | ||
2687 | if (!copy_to_user(&dst->infos, &infos, sizeof infos)) | ||
2688 | err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst); | ||
2689 | } | ||
2690 | return err; | ||
2691 | } | ||
2692 | |||
2693 | static long raw1394_read_cycle_timer32(struct file_info *fi, void __user * uaddr) | ||
2694 | { | ||
2695 | struct raw1394_cycle_timer32 ct; | ||
2696 | int err; | ||
2697 | |||
2698 | err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time); | ||
2699 | if (!err) | ||
2700 | if (copy_to_user(uaddr, &ct, sizeof(ct))) | ||
2701 | err = -EFAULT; | ||
2702 | return err; | ||
2703 | } | ||
2704 | |||
2705 | static long raw1394_compat_ioctl(struct file *file, | ||
2706 | unsigned int cmd, unsigned long arg) | ||
2707 | { | ||
2708 | struct file_info *fi = file->private_data; | ||
2709 | void __user *argp = (void __user *)arg; | ||
2710 | long err; | ||
2711 | |||
2712 | lock_kernel(); | ||
2713 | switch (cmd) { | ||
2714 | /* These requests have same format as long as 'int' has same size. */ | ||
2715 | case RAW1394_IOC_ISO_RECV_INIT: | ||
2716 | case RAW1394_IOC_ISO_RECV_START: | ||
2717 | case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL: | ||
2718 | case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL: | ||
2719 | case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: | ||
2720 | case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: | ||
2721 | case RAW1394_IOC_ISO_RECV_FLUSH: | ||
2722 | case RAW1394_IOC_ISO_XMIT_RECV_STOP: | ||
2723 | case RAW1394_IOC_ISO_XMIT_INIT: | ||
2724 | case RAW1394_IOC_ISO_XMIT_START: | ||
2725 | case RAW1394_IOC_ISO_XMIT_SYNC: | ||
2726 | case RAW1394_IOC_ISO_GET_STATUS: | ||
2727 | case RAW1394_IOC_ISO_SHUTDOWN: | ||
2728 | case RAW1394_IOC_ISO_QUEUE_ACTIVITY: | ||
2729 | err = raw1394_ioctl(NULL, file, cmd, arg); | ||
2730 | break; | ||
2731 | /* These request have different format. */ | ||
2732 | case RAW1394_IOC_ISO_RECV_PACKETS32: | ||
2733 | err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_RECV_PACKETS, argp); | ||
2734 | break; | ||
2735 | case RAW1394_IOC_ISO_XMIT_PACKETS32: | ||
2736 | err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_XMIT_PACKETS, argp); | ||
2737 | break; | ||
2738 | case RAW1394_IOC_GET_CYCLE_TIMER32: | ||
2739 | err = raw1394_read_cycle_timer32(fi, argp); | ||
2740 | break; | ||
2741 | default: | ||
2742 | err = -EINVAL; | ||
2743 | break; | ||
2744 | } | ||
2745 | unlock_kernel(); | ||
2746 | |||
2747 | return err; | ||
2748 | } | ||
2749 | #endif | ||
2750 | |||
2805 | static unsigned int raw1394_poll(struct file *file, poll_table * pt) | 2751 | static unsigned int raw1394_poll(struct file *file, poll_table * pt) |
2806 | { | 2752 | { |
2807 | struct file_info *fi = file->private_data; | 2753 | struct file_info *fi = file->private_data; |
@@ -2861,14 +2807,7 @@ static int raw1394_release(struct inode *inode, struct file *file) | |||
2861 | if (fi->iso_state != RAW1394_ISO_INACTIVE) | 2807 | if (fi->iso_state != RAW1394_ISO_INACTIVE) |
2862 | raw1394_iso_shutdown(fi); | 2808 | raw1394_iso_shutdown(fi); |
2863 | 2809 | ||
2864 | for (i = 0; i < 64; i++) { | ||
2865 | if (fi->listen_channels & (1ULL << i)) { | ||
2866 | hpsb_unlisten_channel(&raw1394_highlevel, fi->host, i); | ||
2867 | } | ||
2868 | } | ||
2869 | |||
2870 | spin_lock_irqsave(&host_info_lock, flags); | 2810 | spin_lock_irqsave(&host_info_lock, flags); |
2871 | fi->listen_channels = 0; | ||
2872 | 2811 | ||
2873 | fail = 0; | 2812 | fail = 0; |
2874 | /* set address-entries invalid */ | 2813 | /* set address-entries invalid */ |
@@ -3030,7 +2969,6 @@ static struct hpsb_highlevel raw1394_highlevel = { | |||
3030 | .add_host = add_host, | 2969 | .add_host = add_host, |
3031 | .remove_host = remove_host, | 2970 | .remove_host = remove_host, |
3032 | .host_reset = host_reset, | 2971 | .host_reset = host_reset, |
3033 | .iso_receive = iso_receive, | ||
3034 | .fcp_request = fcp_request, | 2972 | .fcp_request = fcp_request, |
3035 | }; | 2973 | }; |
3036 | 2974 | ||
@@ -3041,7 +2979,9 @@ static const struct file_operations raw1394_fops = { | |||
3041 | .write = raw1394_write, | 2979 | .write = raw1394_write, |
3042 | .mmap = raw1394_mmap, | 2980 | .mmap = raw1394_mmap, |
3043 | .ioctl = raw1394_ioctl, | 2981 | .ioctl = raw1394_ioctl, |
3044 | // .compat_ioctl = ... someone needs to do this | 2982 | #ifdef CONFIG_COMPAT |
2983 | .compat_ioctl = raw1394_compat_ioctl, | ||
2984 | #endif | ||
3045 | .poll = raw1394_poll, | 2985 | .poll = raw1394_poll, |
3046 | .open = raw1394_open, | 2986 | .open = raw1394_open, |
3047 | .release = raw1394_release, | 2987 | .release = raw1394_release, |
@@ -3054,9 +2994,9 @@ static int __init init_raw1394(void) | |||
3054 | hpsb_register_highlevel(&raw1394_highlevel); | 2994 | hpsb_register_highlevel(&raw1394_highlevel); |
3055 | 2995 | ||
3056 | if (IS_ERR | 2996 | if (IS_ERR |
3057 | (class_device_create | 2997 | (device_create( |
3058 | (hpsb_protocol_class, NULL, | 2998 | hpsb_protocol_class, NULL, |
3059 | MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL, | 2999 | MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), |
3060 | RAW1394_DEVICE_NAME))) { | 3000 | RAW1394_DEVICE_NAME))) { |
3061 | ret = -EFAULT; | 3001 | ret = -EFAULT; |
3062 | goto out_unreg; | 3002 | goto out_unreg; |
@@ -3083,9 +3023,9 @@ static int __init init_raw1394(void) | |||
3083 | goto out; | 3023 | goto out; |
3084 | 3024 | ||
3085 | out_dev: | 3025 | out_dev: |
3086 | class_device_destroy(hpsb_protocol_class, | 3026 | device_destroy(hpsb_protocol_class, |
3087 | MKDEV(IEEE1394_MAJOR, | 3027 | MKDEV(IEEE1394_MAJOR, |
3088 | IEEE1394_MINOR_BLOCK_RAW1394 * 16)); | 3028 | IEEE1394_MINOR_BLOCK_RAW1394 * 16)); |
3089 | out_unreg: | 3029 | out_unreg: |
3090 | hpsb_unregister_highlevel(&raw1394_highlevel); | 3030 | hpsb_unregister_highlevel(&raw1394_highlevel); |
3091 | out: | 3031 | out: |
@@ -3094,9 +3034,9 @@ static int __init init_raw1394(void) | |||
3094 | 3034 | ||
3095 | static void __exit cleanup_raw1394(void) | 3035 | static void __exit cleanup_raw1394(void) |
3096 | { | 3036 | { |
3097 | class_device_destroy(hpsb_protocol_class, | 3037 | device_destroy(hpsb_protocol_class, |
3098 | MKDEV(IEEE1394_MAJOR, | 3038 | MKDEV(IEEE1394_MAJOR, |
3099 | IEEE1394_MINOR_BLOCK_RAW1394 * 16)); | 3039 | IEEE1394_MINOR_BLOCK_RAW1394 * 16)); |
3100 | cdev_del(&raw1394_cdev); | 3040 | cdev_del(&raw1394_cdev); |
3101 | hpsb_unregister_highlevel(&raw1394_highlevel); | 3041 | hpsb_unregister_highlevel(&raw1394_highlevel); |
3102 | hpsb_unregister_protocol(&raw1394_driver); | 3042 | hpsb_unregister_protocol(&raw1394_driver); |