diff options
29 files changed, 663 insertions, 371 deletions
diff --git a/Documentation/filesystems/pohmelfs/design_notes.txt b/Documentation/filesystems/pohmelfs/design_notes.txt index 6d6db60d567d..dcf833587162 100644 --- a/Documentation/filesystems/pohmelfs/design_notes.txt +++ b/Documentation/filesystems/pohmelfs/design_notes.txt | |||
@@ -56,9 +56,10 @@ workloads and can fully utilize the bandwidth to the servers when doing bulk | |||
56 | data transfers. | 56 | data transfers. |
57 | 57 | ||
58 | POHMELFS clients operate with a working set of servers and are capable of balancing read-only | 58 | POHMELFS clients operate with a working set of servers and are capable of balancing read-only |
59 | operations (like lookups or directory listings) between them. | 59 | operations (like lookups or directory listings) between them according to IO priorities. |
60 | Administrators can add or remove servers from the set at run-time via special commands (described | 60 | Administrators can add or remove servers from the set at run-time via special commands (described |
61 | in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers. | 61 | in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers, which are connected |
62 | with write permission turned on. IO priority and permissions can be changed in run-time. | ||
62 | 63 | ||
63 | POHMELFS is capable of full data channel encryption and/or strong crypto hashing. | 64 | POHMELFS is capable of full data channel encryption and/or strong crypto hashing. |
64 | One can select any kernel supported cipher, encryption mode, hash type and operation mode | 65 | One can select any kernel supported cipher, encryption mode, hash type and operation mode |
diff --git a/Documentation/filesystems/pohmelfs/info.txt b/Documentation/filesystems/pohmelfs/info.txt index 4e3d50157083..db2e41393626 100644 --- a/Documentation/filesystems/pohmelfs/info.txt +++ b/Documentation/filesystems/pohmelfs/info.txt | |||
@@ -1,6 +1,8 @@ | |||
1 | POHMELFS usage information. | 1 | POHMELFS usage information. |
2 | 2 | ||
3 | Mount options: | 3 | Mount options. |
4 | All but index, number of crypto threads and maximum IO size can changed via remount. | ||
5 | |||
4 | idx=%u | 6 | idx=%u |
5 | Each mountpoint is associated with a special index via this option. | 7 | Each mountpoint is associated with a special index via this option. |
6 | Administrator can add or remove servers from the given index, so all mounts, | 8 | Administrator can add or remove servers from the given index, so all mounts, |
@@ -52,16 +54,27 @@ mcache_timeout=%u | |||
52 | 54 | ||
53 | Usage examples. | 55 | Usage examples. |
54 | 56 | ||
55 | Add (or remove if it already exists) server server1.net:1025 into the working set with index $idx | 57 | Add server server1.net:1025 into the working set with index $idx |
56 | with appropriate hash algorithm and key file and cipher algorithm, mode and key file: | 58 | with appropriate hash algorithm and key file and cipher algorithm, mode and key file: |
57 | $cfg -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key | 59 | $cfg A add -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key |
58 | 60 | ||
59 | Mount filesystem with given index $idx to /mnt mountpoint. | 61 | Mount filesystem with given index $idx to /mnt mountpoint. |
60 | Client will connect to all servers specified in the working set via previous command: | 62 | Client will connect to all servers specified in the working set via previous command: |
61 | mount -t pohmel -o idx=$idx q /mnt | 63 | mount -t pohmel -o idx=$idx q /mnt |
62 | 64 | ||
63 | One can add or remove servers from working set after mounting too. | 65 | Change permissions to read-only (-I 1 option, '-I 2' - write-only, 3 - rw): |
66 | $cfg A modify -a server1.net -p 1025 -i $idx -I 1 | ||
67 | |||
68 | Change IO priority to 123 (node with the highest priority gets read requests). | ||
69 | $cfg A modify -a server1.net -p 1025 -i $idx -P 123 | ||
64 | 70 | ||
71 | One can check currect status of all connections in the mountstats file: | ||
72 | # cat /proc/$PID/mountstats | ||
73 | ... | ||
74 | device none mounted on /mnt with fstype pohmel | ||
75 | idx addr(:port) socket_type protocol active priority permissions | ||
76 | 0 server1.net:1026 1 6 1 250 1 | ||
77 | 0 server2.net:1025 1 6 1 123 3 | ||
65 | 78 | ||
66 | Server installation. | 79 | Server installation. |
67 | 80 | ||
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 79e90fed27d3..299d29d1dadb 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c | |||
@@ -41,6 +41,8 @@ static int binder_last_id; | |||
41 | static struct proc_dir_entry *binder_proc_dir_entry_root; | 41 | static struct proc_dir_entry *binder_proc_dir_entry_root; |
42 | static struct proc_dir_entry *binder_proc_dir_entry_proc; | 42 | static struct proc_dir_entry *binder_proc_dir_entry_proc; |
43 | static struct hlist_head binder_dead_nodes; | 43 | static struct hlist_head binder_dead_nodes; |
44 | static HLIST_HEAD(binder_deferred_list); | ||
45 | static DEFINE_MUTEX(binder_deferred_lock); | ||
44 | 46 | ||
45 | static int binder_read_proc_proc( | 47 | static int binder_read_proc_proc( |
46 | char *page, char **start, off_t off, int count, int *eof, void *data); | 48 | char *page, char **start, off_t off, int count, int *eof, void *data); |
@@ -54,11 +56,7 @@ static int binder_read_proc_proc( | |||
54 | #define SZ_4M 0x400000 | 56 | #define SZ_4M 0x400000 |
55 | #endif | 57 | #endif |
56 | 58 | ||
57 | #ifndef __i386__ | ||
58 | #define FORBIDDEN_MMAP_FLAGS (VM_WRITE | VM_EXEC) | ||
59 | #else | ||
60 | #define FORBIDDEN_MMAP_FLAGS (VM_WRITE) | 59 | #define FORBIDDEN_MMAP_FLAGS (VM_WRITE) |
61 | #endif | ||
62 | 60 | ||
63 | #define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64) | 61 | #define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64) |
64 | 62 | ||
@@ -236,6 +234,12 @@ struct binder_buffer { | |||
236 | uint8_t data[0]; | 234 | uint8_t data[0]; |
237 | }; | 235 | }; |
238 | 236 | ||
237 | enum { | ||
238 | BINDER_DEFERRED_PUT_FILES = 0x01, | ||
239 | BINDER_DEFERRED_FLUSH = 0x02, | ||
240 | BINDER_DEFERRED_RELEASE = 0x04, | ||
241 | }; | ||
242 | |||
239 | struct binder_proc { | 243 | struct binder_proc { |
240 | struct hlist_node proc_node; | 244 | struct hlist_node proc_node; |
241 | struct rb_root threads; | 245 | struct rb_root threads; |
@@ -245,8 +249,11 @@ struct binder_proc { | |||
245 | int pid; | 249 | int pid; |
246 | struct vm_area_struct *vma; | 250 | struct vm_area_struct *vma; |
247 | struct task_struct *tsk; | 251 | struct task_struct *tsk; |
252 | struct files_struct *files; | ||
253 | struct hlist_node deferred_work_node; | ||
254 | int deferred_work; | ||
248 | void *buffer; | 255 | void *buffer; |
249 | size_t user_buffer_offset; | 256 | ptrdiff_t user_buffer_offset; |
250 | 257 | ||
251 | struct list_head buffers; | 258 | struct list_head buffers; |
252 | struct rb_root free_buffers; | 259 | struct rb_root free_buffers; |
@@ -310,12 +317,14 @@ struct binder_transaction { | |||
310 | uid_t sender_euid; | 317 | uid_t sender_euid; |
311 | }; | 318 | }; |
312 | 319 | ||
320 | static void binder_defer_work(struct binder_proc *proc, int defer); | ||
321 | |||
313 | /* | 322 | /* |
314 | * copied from get_unused_fd_flags | 323 | * copied from get_unused_fd_flags |
315 | */ | 324 | */ |
316 | int task_get_unused_fd_flags(struct task_struct *tsk, int flags) | 325 | int task_get_unused_fd_flags(struct binder_proc *proc, int flags) |
317 | { | 326 | { |
318 | struct files_struct *files = get_files_struct(tsk); | 327 | struct files_struct *files = proc->files; |
319 | int fd, error; | 328 | int fd, error; |
320 | struct fdtable *fdt; | 329 | struct fdtable *fdt; |
321 | unsigned long rlim_cur; | 330 | unsigned long rlim_cur; |
@@ -337,9 +346,9 @@ repeat: | |||
337 | * will limit the total number of files that can be opened. | 346 | * will limit the total number of files that can be opened. |
338 | */ | 347 | */ |
339 | rlim_cur = 0; | 348 | rlim_cur = 0; |
340 | if (lock_task_sighand(tsk, &irqs)) { | 349 | if (lock_task_sighand(proc->tsk, &irqs)) { |
341 | rlim_cur = tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur; | 350 | rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur; |
342 | unlock_task_sighand(tsk, &irqs); | 351 | unlock_task_sighand(proc->tsk, &irqs); |
343 | } | 352 | } |
344 | if (fd >= rlim_cur) | 353 | if (fd >= rlim_cur) |
345 | goto out; | 354 | goto out; |
@@ -375,7 +384,6 @@ repeat: | |||
375 | 384 | ||
376 | out: | 385 | out: |
377 | spin_unlock(&files->file_lock); | 386 | spin_unlock(&files->file_lock); |
378 | put_files_struct(files); | ||
379 | return error; | 387 | return error; |
380 | } | 388 | } |
381 | 389 | ||
@@ -383,9 +391,9 @@ out: | |||
383 | * copied from fd_install | 391 | * copied from fd_install |
384 | */ | 392 | */ |
385 | static void task_fd_install( | 393 | static void task_fd_install( |
386 | struct task_struct *tsk, unsigned int fd, struct file *file) | 394 | struct binder_proc *proc, unsigned int fd, struct file *file) |
387 | { | 395 | { |
388 | struct files_struct *files = get_files_struct(tsk); | 396 | struct files_struct *files = proc->files; |
389 | struct fdtable *fdt; | 397 | struct fdtable *fdt; |
390 | 398 | ||
391 | if (files == NULL) | 399 | if (files == NULL) |
@@ -396,7 +404,6 @@ static void task_fd_install( | |||
396 | BUG_ON(fdt->fd[fd] != NULL); | 404 | BUG_ON(fdt->fd[fd] != NULL); |
397 | rcu_assign_pointer(fdt->fd[fd], file); | 405 | rcu_assign_pointer(fdt->fd[fd], file); |
398 | spin_unlock(&files->file_lock); | 406 | spin_unlock(&files->file_lock); |
399 | put_files_struct(files); | ||
400 | } | 407 | } |
401 | 408 | ||
402 | /* | 409 | /* |
@@ -413,10 +420,10 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd) | |||
413 | /* | 420 | /* |
414 | * copied from sys_close | 421 | * copied from sys_close |
415 | */ | 422 | */ |
416 | static long task_close_fd(struct task_struct *tsk, unsigned int fd) | 423 | static long task_close_fd(struct binder_proc *proc, unsigned int fd) |
417 | { | 424 | { |
418 | struct file *filp; | 425 | struct file *filp; |
419 | struct files_struct *files = get_files_struct(tsk); | 426 | struct files_struct *files = proc->files; |
420 | struct fdtable *fdt; | 427 | struct fdtable *fdt; |
421 | int retval; | 428 | int retval; |
422 | 429 | ||
@@ -443,12 +450,10 @@ static long task_close_fd(struct task_struct *tsk, unsigned int fd) | |||
443 | retval == -ERESTART_RESTARTBLOCK)) | 450 | retval == -ERESTART_RESTARTBLOCK)) |
444 | retval = -EINTR; | 451 | retval = -EINTR; |
445 | 452 | ||
446 | put_files_struct(files); | ||
447 | return retval; | 453 | return retval; |
448 | 454 | ||
449 | out_unlock: | 455 | out_unlock: |
450 | spin_unlock(&files->file_lock); | 456 | spin_unlock(&files->file_lock); |
451 | put_files_struct(files); | ||
452 | return -EBADF; | 457 | return -EBADF; |
453 | } | 458 | } |
454 | 459 | ||
@@ -618,7 +623,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, | |||
618 | proc->pid, page_addr); | 623 | proc->pid, page_addr); |
619 | goto err_map_kernel_failed; | 624 | goto err_map_kernel_failed; |
620 | } | 625 | } |
621 | user_page_addr = (size_t)page_addr + proc->user_buffer_offset; | 626 | user_page_addr = |
627 | (uintptr_t)page_addr + proc->user_buffer_offset; | ||
622 | ret = vm_insert_page(vma, user_page_addr, page[0]); | 628 | ret = vm_insert_page(vma, user_page_addr, page[0]); |
623 | if (ret) { | 629 | if (ret) { |
624 | printk(KERN_ERR "binder: %d: binder_alloc_buf failed " | 630 | printk(KERN_ERR "binder: %d: binder_alloc_buf failed " |
@@ -639,7 +645,7 @@ free_range: | |||
639 | page_addr -= PAGE_SIZE) { | 645 | page_addr -= PAGE_SIZE) { |
640 | page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; | 646 | page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; |
641 | if (vma) | 647 | if (vma) |
642 | zap_page_range(vma, (size_t)page_addr + | 648 | zap_page_range(vma, (uintptr_t)page_addr + |
643 | proc->user_buffer_offset, PAGE_SIZE, NULL); | 649 | proc->user_buffer_offset, PAGE_SIZE, NULL); |
644 | err_vm_insert_page_failed: | 650 | err_vm_insert_page_failed: |
645 | unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE); | 651 | unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE); |
@@ -720,18 +726,19 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, | |||
720 | "er %p size %zd\n", proc->pid, size, buffer, buffer_size); | 726 | "er %p size %zd\n", proc->pid, size, buffer, buffer_size); |
721 | 727 | ||
722 | has_page_addr = | 728 | has_page_addr = |
723 | (void *)(((size_t)buffer->data + buffer_size) & PAGE_MASK); | 729 | (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK); |
724 | if (n == NULL) { | 730 | if (n == NULL) { |
725 | if (size + sizeof(struct binder_buffer) + 4 >= buffer_size) | 731 | if (size + sizeof(struct binder_buffer) + 4 >= buffer_size) |
726 | buffer_size = size; /* no room for other buffers */ | 732 | buffer_size = size; /* no room for other buffers */ |
727 | else | 733 | else |
728 | buffer_size = size + sizeof(struct binder_buffer); | 734 | buffer_size = size + sizeof(struct binder_buffer); |
729 | } | 735 | } |
730 | end_page_addr = (void *)PAGE_ALIGN((size_t)buffer->data + buffer_size); | 736 | end_page_addr = |
737 | (void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size); | ||
731 | if (end_page_addr > has_page_addr) | 738 | if (end_page_addr > has_page_addr) |
732 | end_page_addr = has_page_addr; | 739 | end_page_addr = has_page_addr; |
733 | if (binder_update_page_range(proc, 1, | 740 | if (binder_update_page_range(proc, 1, |
734 | (void *)PAGE_ALIGN((size_t)buffer->data), end_page_addr, NULL)) | 741 | (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL)) |
735 | return NULL; | 742 | return NULL; |
736 | 743 | ||
737 | rb_erase(best_fit, &proc->free_buffers); | 744 | rb_erase(best_fit, &proc->free_buffers); |
@@ -762,12 +769,12 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, | |||
762 | 769 | ||
763 | static void *buffer_start_page(struct binder_buffer *buffer) | 770 | static void *buffer_start_page(struct binder_buffer *buffer) |
764 | { | 771 | { |
765 | return (void *)((size_t)buffer & PAGE_MASK); | 772 | return (void *)((uintptr_t)buffer & PAGE_MASK); |
766 | } | 773 | } |
767 | 774 | ||
768 | static void *buffer_end_page(struct binder_buffer *buffer) | 775 | static void *buffer_end_page(struct binder_buffer *buffer) |
769 | { | 776 | { |
770 | return (void *)(((size_t)(buffer + 1) - 1) & PAGE_MASK); | 777 | return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK); |
771 | } | 778 | } |
772 | 779 | ||
773 | static void binder_delete_free_buffer( | 780 | static void binder_delete_free_buffer( |
@@ -845,8 +852,8 @@ static void binder_free_buf( | |||
845 | } | 852 | } |
846 | 853 | ||
847 | binder_update_page_range(proc, 0, | 854 | binder_update_page_range(proc, 0, |
848 | (void *)PAGE_ALIGN((size_t)buffer->data), | 855 | (void *)PAGE_ALIGN((uintptr_t)buffer->data), |
849 | (void *)(((size_t)buffer->data + buffer_size) & PAGE_MASK), | 856 | (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK), |
850 | NULL); | 857 | NULL); |
851 | rb_erase(&buffer->rb_node, &proc->allocated_buffers); | 858 | rb_erase(&buffer->rb_node, &proc->allocated_buffers); |
852 | buffer->free = 1; | 859 | buffer->free = 1; |
@@ -1345,6 +1352,17 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread, | |||
1345 | if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { | 1352 | if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { |
1346 | struct binder_transaction *tmp; | 1353 | struct binder_transaction *tmp; |
1347 | tmp = thread->transaction_stack; | 1354 | tmp = thread->transaction_stack; |
1355 | if (tmp->to_thread != thread) { | ||
1356 | binder_user_error("binder: %d:%d got new " | ||
1357 | "transaction with bad transaction stack" | ||
1358 | ", transaction %d has target %d:%d\n", | ||
1359 | proc->pid, thread->pid, tmp->debug_id, | ||
1360 | tmp->to_proc ? tmp->to_proc->pid : 0, | ||
1361 | tmp->to_thread ? | ||
1362 | tmp->to_thread->pid : 0); | ||
1363 | return_error = BR_FAILED_REPLY; | ||
1364 | goto err_bad_call_stack; | ||
1365 | } | ||
1348 | while (tmp) { | 1366 | while (tmp) { |
1349 | if (tmp->from && tmp->from->proc == target_proc) | 1367 | if (tmp->from && tmp->from->proc == target_proc) |
1350 | target_thread = tmp->from; | 1368 | target_thread = tmp->from; |
@@ -1434,10 +1452,19 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread, | |||
1434 | return_error = BR_FAILED_REPLY; | 1452 | return_error = BR_FAILED_REPLY; |
1435 | goto err_copy_data_failed; | 1453 | goto err_copy_data_failed; |
1436 | } | 1454 | } |
1455 | if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { | ||
1456 | binder_user_error("binder: %d:%d got transaction with " | ||
1457 | "invalid offsets size, %zd\n", | ||
1458 | proc->pid, thread->pid, tr->offsets_size); | ||
1459 | return_error = BR_FAILED_REPLY; | ||
1460 | goto err_bad_offset; | ||
1461 | } | ||
1437 | off_end = (void *)offp + tr->offsets_size; | 1462 | off_end = (void *)offp + tr->offsets_size; |
1438 | for (; offp < off_end; offp++) { | 1463 | for (; offp < off_end; offp++) { |
1439 | struct flat_binder_object *fp; | 1464 | struct flat_binder_object *fp; |
1440 | if (*offp > t->buffer->data_size - sizeof(*fp)) { | 1465 | if (*offp > t->buffer->data_size - sizeof(*fp) || |
1466 | t->buffer->data_size < sizeof(*fp) || | ||
1467 | !IS_ALIGNED(*offp, sizeof(void *))) { | ||
1441 | binder_user_error("binder: %d:%d got transaction with " | 1468 | binder_user_error("binder: %d:%d got transaction with " |
1442 | "invalid offset, %zd\n", | 1469 | "invalid offset, %zd\n", |
1443 | proc->pid, thread->pid, *offp); | 1470 | proc->pid, thread->pid, *offp); |
@@ -1544,13 +1571,13 @@ binder_transaction(struct binder_proc *proc, struct binder_thread *thread, | |||
1544 | return_error = BR_FAILED_REPLY; | 1571 | return_error = BR_FAILED_REPLY; |
1545 | goto err_fget_failed; | 1572 | goto err_fget_failed; |
1546 | } | 1573 | } |
1547 | target_fd = task_get_unused_fd_flags(target_proc->tsk, O_CLOEXEC); | 1574 | target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); |
1548 | if (target_fd < 0) { | 1575 | if (target_fd < 0) { |
1549 | fput(file); | 1576 | fput(file); |
1550 | return_error = BR_FAILED_REPLY; | 1577 | return_error = BR_FAILED_REPLY; |
1551 | goto err_get_unused_fd_failed; | 1578 | goto err_get_unused_fd_failed; |
1552 | } | 1579 | } |
1553 | task_fd_install(target_proc->tsk, target_fd, file); | 1580 | task_fd_install(target_proc, target_fd, file); |
1554 | if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) | 1581 | if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) |
1555 | printk(KERN_INFO " fd %ld -> %d\n", fp->handle, target_fd); | 1582 | printk(KERN_INFO " fd %ld -> %d\n", fp->handle, target_fd); |
1556 | /* TODO: fput? */ | 1583 | /* TODO: fput? */ |
@@ -1655,7 +1682,9 @@ binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer | |||
1655 | off_end = (void *)offp + buffer->offsets_size; | 1682 | off_end = (void *)offp + buffer->offsets_size; |
1656 | for (; offp < off_end; offp++) { | 1683 | for (; offp < off_end; offp++) { |
1657 | struct flat_binder_object *fp; | 1684 | struct flat_binder_object *fp; |
1658 | if (*offp > buffer->data_size - sizeof(*fp)) { | 1685 | if (*offp > buffer->data_size - sizeof(*fp) || |
1686 | buffer->data_size < sizeof(*fp) || | ||
1687 | !IS_ALIGNED(*offp, sizeof(void *))) { | ||
1659 | printk(KERN_ERR "binder: transaction release %d bad" | 1688 | printk(KERN_ERR "binder: transaction release %d bad" |
1660 | "offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); | 1689 | "offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); |
1661 | continue; | 1690 | continue; |
@@ -1691,7 +1720,7 @@ binder_transaction_buffer_release(struct binder_proc *proc, struct binder_buffer | |||
1691 | if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) | 1720 | if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) |
1692 | printk(KERN_INFO " fd %ld\n", fp->handle); | 1721 | printk(KERN_INFO " fd %ld\n", fp->handle); |
1693 | if (failed_at) | 1722 | if (failed_at) |
1694 | task_close_fd(proc->tsk, fp->handle); | 1723 | task_close_fd(proc, fp->handle); |
1695 | break; | 1724 | break; |
1696 | 1725 | ||
1697 | default: | 1726 | default: |
@@ -2340,7 +2369,7 @@ retry: | |||
2340 | 2369 | ||
2341 | tr.data_size = t->buffer->data_size; | 2370 | tr.data_size = t->buffer->data_size; |
2342 | tr.offsets_size = t->buffer->offsets_size; | 2371 | tr.offsets_size = t->buffer->offsets_size; |
2343 | tr.data.ptr.buffer = (void *)((void *)t->buffer->data + proc->user_buffer_offset); | 2372 | tr.data.ptr.buffer = (void *)t->buffer->data + proc->user_buffer_offset; |
2344 | tr.data.ptr.offsets = tr.data.ptr.buffer + ALIGN(t->buffer->data_size, sizeof(void *)); | 2373 | tr.data.ptr.offsets = tr.data.ptr.buffer + ALIGN(t->buffer->data_size, sizeof(void *)); |
2345 | 2374 | ||
2346 | if (put_user(cmd, (uint32_t __user *)ptr)) | 2375 | if (put_user(cmd, (uint32_t __user *)ptr)) |
@@ -2656,6 +2685,7 @@ static void binder_vma_open(struct vm_area_struct *vma) | |||
2656 | (unsigned long)pgprot_val(vma->vm_page_prot)); | 2685 | (unsigned long)pgprot_val(vma->vm_page_prot)); |
2657 | dump_stack(); | 2686 | dump_stack(); |
2658 | } | 2687 | } |
2688 | |||
2659 | static void binder_vma_close(struct vm_area_struct *vma) | 2689 | static void binder_vma_close(struct vm_area_struct *vma) |
2660 | { | 2690 | { |
2661 | struct binder_proc *proc = vma->vm_private_data; | 2691 | struct binder_proc *proc = vma->vm_private_data; |
@@ -2666,6 +2696,7 @@ static void binder_vma_close(struct vm_area_struct *vma) | |||
2666 | (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, | 2696 | (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, |
2667 | (unsigned long)pgprot_val(vma->vm_page_prot)); | 2697 | (unsigned long)pgprot_val(vma->vm_page_prot)); |
2668 | proc->vma = NULL; | 2698 | proc->vma = NULL; |
2699 | binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); | ||
2669 | } | 2700 | } |
2670 | 2701 | ||
2671 | static struct vm_operations_struct binder_vm_ops = { | 2702 | static struct vm_operations_struct binder_vm_ops = { |
@@ -2698,6 +2729,12 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
2698 | } | 2729 | } |
2699 | vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; | 2730 | vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; |
2700 | 2731 | ||
2732 | if (proc->buffer) { | ||
2733 | ret = -EBUSY; | ||
2734 | failure_string = "already mapped"; | ||
2735 | goto err_already_mapped; | ||
2736 | } | ||
2737 | |||
2701 | area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); | 2738 | area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); |
2702 | if (area == NULL) { | 2739 | if (area == NULL) { |
2703 | ret = -ENOMEM; | 2740 | ret = -ENOMEM; |
@@ -2705,7 +2742,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
2705 | goto err_get_vm_area_failed; | 2742 | goto err_get_vm_area_failed; |
2706 | } | 2743 | } |
2707 | proc->buffer = area->addr; | 2744 | proc->buffer = area->addr; |
2708 | proc->user_buffer_offset = vma->vm_start - (size_t)proc->buffer; | 2745 | proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer; |
2709 | 2746 | ||
2710 | #ifdef CONFIG_CPU_CACHE_VIPT | 2747 | #ifdef CONFIG_CPU_CACHE_VIPT |
2711 | if (cache_is_vipt_aliasing()) { | 2748 | if (cache_is_vipt_aliasing()) { |
@@ -2738,6 +2775,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
2738 | binder_insert_free_buffer(proc, buffer); | 2775 | binder_insert_free_buffer(proc, buffer); |
2739 | proc->free_async_space = proc->buffer_size / 2; | 2776 | proc->free_async_space = proc->buffer_size / 2; |
2740 | barrier(); | 2777 | barrier(); |
2778 | proc->files = get_files_struct(current); | ||
2741 | proc->vma = vma; | 2779 | proc->vma = vma; |
2742 | 2780 | ||
2743 | /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ | 2781 | /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ |
@@ -2745,10 +2783,12 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) | |||
2745 | 2783 | ||
2746 | err_alloc_small_buf_failed: | 2784 | err_alloc_small_buf_failed: |
2747 | kfree(proc->pages); | 2785 | kfree(proc->pages); |
2786 | proc->pages = NULL; | ||
2748 | err_alloc_pages_failed: | 2787 | err_alloc_pages_failed: |
2749 | vfree(proc->buffer); | 2788 | vfree(proc->buffer); |
2789 | proc->buffer = NULL; | ||
2750 | err_get_vm_area_failed: | 2790 | err_get_vm_area_failed: |
2751 | mutex_unlock(&binder_lock); | 2791 | err_already_mapped: |
2752 | err_bad_arg: | 2792 | err_bad_arg: |
2753 | printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); | 2793 | printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); |
2754 | return ret; | 2794 | return ret; |
@@ -2780,6 +2820,7 @@ static int binder_open(struct inode *nodp, struct file *filp) | |||
2780 | if (binder_proc_dir_entry_proc) { | 2820 | if (binder_proc_dir_entry_proc) { |
2781 | char strbuf[11]; | 2821 | char strbuf[11]; |
2782 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); | 2822 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); |
2823 | remove_proc_entry(strbuf, binder_proc_dir_entry_proc); | ||
2783 | create_proc_read_entry(strbuf, S_IRUGO, binder_proc_dir_entry_proc, binder_read_proc_proc, proc); | 2824 | create_proc_read_entry(strbuf, S_IRUGO, binder_proc_dir_entry_proc, binder_read_proc_proc, proc); |
2784 | } | 2825 | } |
2785 | 2826 | ||
@@ -2788,11 +2829,17 @@ static int binder_open(struct inode *nodp, struct file *filp) | |||
2788 | 2829 | ||
2789 | static int binder_flush(struct file *filp, fl_owner_t id) | 2830 | static int binder_flush(struct file *filp, fl_owner_t id) |
2790 | { | 2831 | { |
2791 | struct rb_node *n; | ||
2792 | struct binder_proc *proc = filp->private_data; | 2832 | struct binder_proc *proc = filp->private_data; |
2793 | int wake_count = 0; | ||
2794 | 2833 | ||
2795 | mutex_lock(&binder_lock); | 2834 | binder_defer_work(proc, BINDER_DEFERRED_FLUSH); |
2835 | |||
2836 | return 0; | ||
2837 | } | ||
2838 | |||
2839 | static void binder_deferred_flush(struct binder_proc *proc) | ||
2840 | { | ||
2841 | struct rb_node *n; | ||
2842 | int wake_count = 0; | ||
2796 | for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { | 2843 | for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { |
2797 | struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); | 2844 | struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); |
2798 | thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; | 2845 | thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; |
@@ -2802,28 +2849,35 @@ static int binder_flush(struct file *filp, fl_owner_t id) | |||
2802 | } | 2849 | } |
2803 | } | 2850 | } |
2804 | wake_up_interruptible_all(&proc->wait); | 2851 | wake_up_interruptible_all(&proc->wait); |
2805 | mutex_unlock(&binder_lock); | ||
2806 | 2852 | ||
2807 | if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) | 2853 | if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE) |
2808 | printk(KERN_INFO "binder_flush: %d woke %d threads\n", proc->pid, wake_count); | 2854 | printk(KERN_INFO "binder_flush: %d woke %d threads\n", proc->pid, wake_count); |
2809 | |||
2810 | return 0; | ||
2811 | } | 2855 | } |
2812 | 2856 | ||
2813 | static int binder_release(struct inode *nodp, struct file *filp) | 2857 | static int binder_release(struct inode *nodp, struct file *filp) |
2814 | { | 2858 | { |
2815 | struct hlist_node *pos; | ||
2816 | struct binder_transaction *t; | ||
2817 | struct rb_node *n; | ||
2818 | struct binder_proc *proc = filp->private_data; | 2859 | struct binder_proc *proc = filp->private_data; |
2819 | int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count; | ||
2820 | |||
2821 | if (binder_proc_dir_entry_proc) { | 2860 | if (binder_proc_dir_entry_proc) { |
2822 | char strbuf[11]; | 2861 | char strbuf[11]; |
2823 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); | 2862 | snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); |
2824 | remove_proc_entry(strbuf, binder_proc_dir_entry_proc); | 2863 | remove_proc_entry(strbuf, binder_proc_dir_entry_proc); |
2825 | } | 2864 | } |
2826 | mutex_lock(&binder_lock); | 2865 | |
2866 | binder_defer_work(proc, BINDER_DEFERRED_RELEASE); | ||
2867 | |||
2868 | return 0; | ||
2869 | } | ||
2870 | |||
2871 | static void binder_deferred_release(struct binder_proc *proc) | ||
2872 | { | ||
2873 | struct hlist_node *pos; | ||
2874 | struct binder_transaction *t; | ||
2875 | struct rb_node *n; | ||
2876 | int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count; | ||
2877 | |||
2878 | BUG_ON(proc->vma); | ||
2879 | BUG_ON(proc->files); | ||
2880 | |||
2827 | hlist_del(&proc->proc_node); | 2881 | hlist_del(&proc->proc_node); |
2828 | if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { | 2882 | if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { |
2829 | if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) | 2883 | if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER) |
@@ -2897,7 +2951,6 @@ static int binder_release(struct inode *nodp, struct file *filp) | |||
2897 | } | 2951 | } |
2898 | 2952 | ||
2899 | binder_stats.obj_deleted[BINDER_STAT_PROC]++; | 2953 | binder_stats.obj_deleted[BINDER_STAT_PROC]++; |
2900 | mutex_unlock(&binder_lock); | ||
2901 | 2954 | ||
2902 | page_count = 0; | 2955 | page_count = 0; |
2903 | if (proc->pages) { | 2956 | if (proc->pages) { |
@@ -2921,7 +2974,57 @@ static int binder_release(struct inode *nodp, struct file *filp) | |||
2921 | proc->pid, threads, nodes, incoming_refs, outgoing_refs, active_transactions, buffers, page_count); | 2974 | proc->pid, threads, nodes, incoming_refs, outgoing_refs, active_transactions, buffers, page_count); |
2922 | 2975 | ||
2923 | kfree(proc); | 2976 | kfree(proc); |
2924 | return 0; | 2977 | } |
2978 | |||
2979 | static void binder_deferred_func(struct work_struct *work) | ||
2980 | { | ||
2981 | struct binder_proc *proc; | ||
2982 | struct files_struct *files; | ||
2983 | |||
2984 | int defer; | ||
2985 | do { | ||
2986 | mutex_lock(&binder_lock); | ||
2987 | mutex_lock(&binder_deferred_lock); | ||
2988 | if (!hlist_empty(&binder_deferred_list)) { | ||
2989 | proc = hlist_entry(binder_deferred_list.first, | ||
2990 | struct binder_proc, deferred_work_node); | ||
2991 | hlist_del_init(&proc->deferred_work_node); | ||
2992 | defer = proc->deferred_work; | ||
2993 | proc->deferred_work = 0; | ||
2994 | } else { | ||
2995 | proc = NULL; | ||
2996 | defer = 0; | ||
2997 | } | ||
2998 | mutex_unlock(&binder_deferred_lock); | ||
2999 | |||
3000 | files = NULL; | ||
3001 | if (defer & BINDER_DEFERRED_PUT_FILES) | ||
3002 | if ((files = proc->files)) | ||
3003 | proc->files = NULL; | ||
3004 | |||
3005 | if (defer & BINDER_DEFERRED_FLUSH) | ||
3006 | binder_deferred_flush(proc); | ||
3007 | |||
3008 | if (defer & BINDER_DEFERRED_RELEASE) | ||
3009 | binder_deferred_release(proc); /* frees proc */ | ||
3010 | |||
3011 | mutex_unlock(&binder_lock); | ||
3012 | if (files) | ||
3013 | put_files_struct(files); | ||
3014 | } while (proc); | ||
3015 | } | ||
3016 | static DECLARE_WORK(binder_deferred_work, binder_deferred_func); | ||
3017 | |||
3018 | static void binder_defer_work(struct binder_proc *proc, int defer) | ||
3019 | { | ||
3020 | mutex_lock(&binder_deferred_lock); | ||
3021 | proc->deferred_work |= defer; | ||
3022 | if (hlist_unhashed(&proc->deferred_work_node)) { | ||
3023 | hlist_add_head(&proc->deferred_work_node, | ||
3024 | &binder_deferred_list); | ||
3025 | schedule_work(&binder_deferred_work); | ||
3026 | } | ||
3027 | mutex_unlock(&binder_deferred_lock); | ||
2925 | } | 3028 | } |
2926 | 3029 | ||
2927 | static char *print_binder_transaction(char *buf, char *end, const char *prefix, struct binder_transaction *t) | 3030 | static char *print_binder_transaction(char *buf, char *end, const char *prefix, struct binder_transaction *t) |
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c index 6f6e36a3bd9f..c8af9a868d62 100644 --- a/drivers/staging/at76_usb/at76_usb.c +++ b/drivers/staging/at76_usb/at76_usb.c | |||
@@ -5259,6 +5259,18 @@ static int at76_alloc_urbs(struct at76_priv *priv, | |||
5259 | return 0; | 5259 | return 0; |
5260 | } | 5260 | } |
5261 | 5261 | ||
5262 | static const struct net_device_ops at76_netdev_ops = { | ||
5263 | .ndo_open = at76_open, | ||
5264 | .ndo_stop = at76_stop, | ||
5265 | .ndo_get_stats = at76_get_stats, | ||
5266 | .ndo_start_xmit = at76_tx, | ||
5267 | .ndo_tx_timeout = at76_tx_timeout, | ||
5268 | .ndo_set_multicast_list = at76_set_multicast, | ||
5269 | .ndo_set_mac_address = at76_set_mac_address, | ||
5270 | .ndo_validate_addr = eth_validate_addr, | ||
5271 | .ndo_change_mtu = eth_change_mtu, | ||
5272 | }; | ||
5273 | |||
5262 | /* Register network device and initialize the hardware */ | 5274 | /* Register network device and initialize the hardware */ |
5263 | static int at76_init_new_device(struct at76_priv *priv, | 5275 | static int at76_init_new_device(struct at76_priv *priv, |
5264 | struct usb_interface *interface) | 5276 | struct usb_interface *interface) |
@@ -5303,21 +5315,15 @@ static int at76_init_new_device(struct at76_priv *priv, | |||
5303 | priv->scan_mode = SCAN_TYPE_ACTIVE; | 5315 | priv->scan_mode = SCAN_TYPE_ACTIVE; |
5304 | 5316 | ||
5305 | netdev->flags &= ~IFF_MULTICAST; /* not yet or never */ | 5317 | netdev->flags &= ~IFF_MULTICAST; /* not yet or never */ |
5306 | netdev->open = at76_open; | 5318 | netdev->netdev_ops = &at76_netdev_ops; |
5307 | netdev->stop = at76_stop; | ||
5308 | netdev->get_stats = at76_get_stats; | ||
5309 | netdev->ethtool_ops = &at76_ethtool_ops; | 5319 | netdev->ethtool_ops = &at76_ethtool_ops; |
5310 | 5320 | ||
5311 | /* Add pointers to enable iwspy support. */ | 5321 | /* Add pointers to enable iwspy support. */ |
5312 | priv->wireless_data.spy_data = &priv->spy_data; | 5322 | priv->wireless_data.spy_data = &priv->spy_data; |
5313 | netdev->wireless_data = &priv->wireless_data; | 5323 | netdev->wireless_data = &priv->wireless_data; |
5314 | 5324 | ||
5315 | netdev->hard_start_xmit = at76_tx; | ||
5316 | netdev->tx_timeout = at76_tx_timeout; | ||
5317 | netdev->watchdog_timeo = 2 * HZ; | 5325 | netdev->watchdog_timeo = 2 * HZ; |
5318 | netdev->wireless_handlers = &at76_handler_def; | 5326 | netdev->wireless_handlers = &at76_handler_def; |
5319 | netdev->set_multicast_list = at76_set_multicast; | ||
5320 | netdev->set_mac_address = at76_set_mac_address; | ||
5321 | dev_alloc_name(netdev, "wlan%d"); | 5327 | dev_alloc_name(netdev, "wlan%d"); |
5322 | 5328 | ||
5323 | ret = register_netdev(priv->netdev); | 5329 | ret = register_netdev(priv->netdev); |
diff --git a/drivers/staging/epl/VirtualEthernetLinux.c b/drivers/staging/epl/VirtualEthernetLinux.c index 21206c4d22ff..077724a556cc 100644 --- a/drivers/staging/epl/VirtualEthernetLinux.c +++ b/drivers/staging/epl/VirtualEthernetLinux.c | |||
@@ -284,6 +284,17 @@ static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p) | |||
284 | return Ret; | 284 | return Ret; |
285 | } | 285 | } |
286 | 286 | ||
287 | static const struct net_device_ops epl_netdev_ops = { | ||
288 | .ndo_open = VEthOpen, | ||
289 | .ndo_stop = VEthClose, | ||
290 | .ndo_get_stats = VEthGetStats, | ||
291 | .ndo_start_xmit = VEthXmit, | ||
292 | .ndo_tx_timeout = VEthTimeout, | ||
293 | .ndo_change_mtu = eth_change_mtu, | ||
294 | .ndo_set_mac_address = eth_mac_addr, | ||
295 | .ndo_validate_addr = eth_validate_addr, | ||
296 | }; | ||
297 | |||
287 | tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p) | 298 | tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p) |
288 | { | 299 | { |
289 | tEplKernel Ret = kEplSuccessful; | 300 | tEplKernel Ret = kEplSuccessful; |
@@ -299,11 +310,7 @@ tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p) | |||
299 | goto Exit; | 310 | goto Exit; |
300 | } | 311 | } |
301 | 312 | ||
302 | pVEthNetDevice_g->open = VEthOpen; | 313 | pVEthNetDevice_g->netdev_ops = &epl_netdev_ops; |
303 | pVEthNetDevice_g->stop = VEthClose; | ||
304 | pVEthNetDevice_g->get_stats = VEthGetStats; | ||
305 | pVEthNetDevice_g->hard_start_xmit = VEthXmit; | ||
306 | pVEthNetDevice_g->tx_timeout = VEthTimeout; | ||
307 | pVEthNetDevice_g->watchdog_timeo = EPL_VETH_TX_TIMEOUT; | 314 | pVEthNetDevice_g->watchdog_timeo = EPL_VETH_TX_TIMEOUT; |
308 | pVEthNetDevice_g->destructor = free_netdev; | 315 | pVEthNetDevice_g->destructor = free_netdev; |
309 | 316 | ||
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index de65972ff362..951c73d5db20 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c | |||
@@ -112,6 +112,19 @@ void et131x_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp); | |||
112 | void et131x_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); | 112 | void et131x_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); |
113 | void et131x_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); | 113 | void et131x_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); |
114 | 114 | ||
115 | static const struct net_device_ops et131x_netdev_ops = { | ||
116 | .ndo_open = et131x_open, | ||
117 | .ndo_stop = et131x_close, | ||
118 | .ndo_start_xmit = et131x_tx, | ||
119 | .ndo_set_multicast_list = et131x_multicast, | ||
120 | .ndo_tx_timeout = et131x_tx_timeout, | ||
121 | .ndo_change_mtu = et131x_change_mtu, | ||
122 | .ndo_set_mac_address = et131x_set_mac_addr, | ||
123 | .ndo_validate_addr = eth_validate_addr, | ||
124 | .ndo_get_stats = et131x_stats, | ||
125 | .ndo_do_ioctl = et131x_ioctl, | ||
126 | }; | ||
127 | |||
115 | /** | 128 | /** |
116 | * et131x_device_alloc | 129 | * et131x_device_alloc |
117 | * | 130 | * |
@@ -142,16 +155,8 @@ struct net_device *et131x_device_alloc(void) | |||
142 | */ | 155 | */ |
143 | //netdev->init = &et131x_init; | 156 | //netdev->init = &et131x_init; |
144 | //netdev->set_config = &et131x_config; | 157 | //netdev->set_config = &et131x_config; |
145 | netdev->get_stats = &et131x_stats; | ||
146 | netdev->open = &et131x_open; | ||
147 | netdev->stop = &et131x_close; | ||
148 | netdev->do_ioctl = &et131x_ioctl; | ||
149 | netdev->set_multicast_list = &et131x_multicast; | ||
150 | netdev->hard_start_xmit = &et131x_tx; | ||
151 | netdev->tx_timeout = &et131x_tx_timeout; | ||
152 | netdev->watchdog_timeo = ET131X_TX_TIMEOUT; | 158 | netdev->watchdog_timeo = ET131X_TX_TIMEOUT; |
153 | netdev->change_mtu = &et131x_change_mtu; | 159 | netdev->netdev_ops = &et131x_netdev_ops; |
154 | netdev->set_mac_address = &et131x_set_mac_addr; | ||
155 | 160 | ||
156 | //netdev->ethtool_ops = &et131x_ethtool_ops; | 161 | //netdev->ethtool_ops = &et131x_ethtool_ops; |
157 | 162 | ||
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c index 58bfc8d81b3b..f47c0ce2849a 100644 --- a/drivers/staging/go7007/go7007-driver.c +++ b/drivers/staging/go7007/go7007-driver.c | |||
@@ -268,21 +268,6 @@ int go7007_register_encoder(struct go7007 *go) | |||
268 | init_i2c_module(&go->i2c_adapter, | 268 | init_i2c_module(&go->i2c_adapter, |
269 | go->board_info->i2c_devs[i].id, | 269 | go->board_info->i2c_devs[i].id, |
270 | go->board_info->i2c_devs[i].addr); | 270 | go->board_info->i2c_devs[i].addr); |
271 | #ifdef TUNER_SET_TYPE_ADDR | ||
272 | if (go->tuner_type >= 0) { | ||
273 | struct tuner_setup tun_setup = { | ||
274 | .mode_mask = T_ANALOG_TV, | ||
275 | .addr = ADDR_UNSET, | ||
276 | .type = go->tuner_type | ||
277 | }; | ||
278 | i2c_clients_command(&go->i2c_adapter, | ||
279 | TUNER_SET_TYPE_ADDR, &tun_setup); | ||
280 | } | ||
281 | #else | ||
282 | if (go->tuner_type >= 0) | ||
283 | i2c_clients_command(&go->i2c_adapter, | ||
284 | TUNER_SET_TYPE, &go->tuner_type); | ||
285 | #endif | ||
286 | if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) | 271 | if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) |
287 | i2c_clients_command(&go->i2c_adapter, | 272 | i2c_clients_command(&go->i2c_adapter, |
288 | DECODER_SET_CHANNEL, &go->channel_number); | 273 | DECODER_SET_CHANNEL, &go->channel_number); |
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c index 58fddb122372..0a7eeef7c008 100644 --- a/drivers/staging/go7007/wis-sony-tuner.c +++ b/drivers/staging/go7007/wis-sony-tuner.c | |||
@@ -386,6 +386,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
386 | struct wis_sony_tuner *t = i2c_get_clientdata(client); | 386 | struct wis_sony_tuner *t = i2c_get_clientdata(client); |
387 | 387 | ||
388 | switch (cmd) { | 388 | switch (cmd) { |
389 | #if 0 | ||
389 | #ifdef TUNER_SET_TYPE_ADDR | 390 | #ifdef TUNER_SET_TYPE_ADDR |
390 | case TUNER_SET_TYPE_ADDR: | 391 | case TUNER_SET_TYPE_ADDR: |
391 | { | 392 | { |
@@ -463,6 +464,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
463 | t->type, sony_tuners[t->type - 200].name); | 464 | t->type, sony_tuners[t->type - 200].name); |
464 | break; | 465 | break; |
465 | } | 466 | } |
467 | #endif | ||
466 | case VIDIOC_G_FREQUENCY: | 468 | case VIDIOC_G_FREQUENCY: |
467 | { | 469 | { |
468 | struct v4l2_frequency *f = arg; | 470 | struct v4l2_frequency *f = arg; |
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c index 3aa946899ced..e2ac8d60f8c2 100644 --- a/drivers/staging/line6/audio.c +++ b/drivers/staging/line6/audio.c | |||
@@ -27,11 +27,12 @@ int line6_init_audio(struct usb_line6 *line6) | |||
27 | { | 27 | { |
28 | static int dev; | 28 | static int dev; |
29 | struct snd_card *card; | 29 | struct snd_card *card; |
30 | int err; | ||
30 | 31 | ||
31 | card = snd_card_new(line6_index[dev], line6_id[dev], THIS_MODULE, 0); | 32 | err = snd_card_create(line6_index[dev], line6_id[dev], THIS_MODULE, 0, |
32 | 33 | &card); | |
33 | if (card == NULL) | 34 | if (err < 0) |
34 | return -ENOMEM; | 35 | return err; |
35 | 36 | ||
36 | line6->card = card; | 37 | line6->card = card; |
37 | 38 | ||
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c index 565a839589f5..540cbbb826f9 100644 --- a/drivers/staging/otus/usbdrv.c +++ b/drivers/staging/otus/usbdrv.c | |||
@@ -822,6 +822,21 @@ int zfLnxVapXmitFrame(struct sk_buff *skb, struct net_device *dev) | |||
822 | return 0; | 822 | return 0; |
823 | } | 823 | } |
824 | 824 | ||
825 | static const struct net_device_ops vap_netdev_ops = { | ||
826 | .ndo_open = zfLnxVapOpen, | ||
827 | .ndo_stop = zfLnxVapClose, | ||
828 | .ndo_start_xmit = zfLnxVapXmitFrame, | ||
829 | .ndo_get_stats = usbdrv_get_stats, | ||
830 | .ndo_change_mtu = usbdrv_change_mtu, | ||
831 | .ndo_validate_addr = eth_validate_addr, | ||
832 | .ndo_set_mac_address = eth_mac_addr, | ||
833 | #ifdef ZM_HOSTAPD_SUPPORT | ||
834 | .ndo_do_ioctl = usbdrv_ioctl, | ||
835 | #else | ||
836 | .ndo_do_ioctl = NULL, | ||
837 | #endif | ||
838 | }; | ||
839 | |||
825 | int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId) | 840 | int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId) |
826 | { | 841 | { |
827 | /* Allocate net device structure */ | 842 | /* Allocate net device structure */ |
@@ -846,16 +861,7 @@ int zfLnxRegisterVapDev(struct net_device* parentDev, u16_t vapId) | |||
846 | vap[vapId].dev->ml_priv = parentDev->ml_priv; | 861 | vap[vapId].dev->ml_priv = parentDev->ml_priv; |
847 | 862 | ||
848 | //dev->hard_start_xmit = &zd1212_wds_xmit_frame; | 863 | //dev->hard_start_xmit = &zd1212_wds_xmit_frame; |
849 | vap[vapId].dev->hard_start_xmit = &zfLnxVapXmitFrame; | 864 | vap[vapId].dev->netdev_ops = &vap_netdev_ops; |
850 | vap[vapId].dev->open = &zfLnxVapOpen; | ||
851 | vap[vapId].dev->stop = &zfLnxVapClose; | ||
852 | vap[vapId].dev->get_stats = &usbdrv_get_stats; | ||
853 | vap[vapId].dev->change_mtu = &usbdrv_change_mtu; | ||
854 | #ifdef ZM_HOSTAPD_SUPPORT | ||
855 | vap[vapId].dev->do_ioctl = usbdrv_ioctl; | ||
856 | #else | ||
857 | vap[vapId].dev->do_ioctl = NULL; | ||
858 | #endif | ||
859 | vap[vapId].dev->destructor = free_netdev; | 865 | vap[vapId].dev->destructor = free_netdev; |
860 | 866 | ||
861 | vap[vapId].dev->tx_queue_len = 0; | 867 | vap[vapId].dev->tx_queue_len = 0; |
@@ -1068,6 +1074,18 @@ void zfLnxUnlinkAllUrbs(struct usbdrv_private *macp) | |||
1068 | usb_unlink_urb(macp->RegInUrb); | 1074 | usb_unlink_urb(macp->RegInUrb); |
1069 | } | 1075 | } |
1070 | 1076 | ||
1077 | static const struct net_device_ops otus_netdev_ops = { | ||
1078 | .ndo_open = usbdrv_open, | ||
1079 | .ndo_stop = usbdrv_close, | ||
1080 | .ndo_start_xmit = usbdrv_xmit_frame, | ||
1081 | .ndo_change_mtu = usbdrv_change_mtu, | ||
1082 | .ndo_get_stats = usbdrv_get_stats, | ||
1083 | .ndo_set_multicast_list = usbdrv_set_multi, | ||
1084 | .ndo_set_mac_address = usbdrv_set_mac, | ||
1085 | .ndo_do_ioctl = usbdrv_ioctl, | ||
1086 | .ndo_validate_addr = eth_validate_addr, | ||
1087 | }; | ||
1088 | |||
1071 | u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp) | 1089 | u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp) |
1072 | { | 1090 | { |
1073 | //unsigned char addr[6]; | 1091 | //unsigned char addr[6]; |
@@ -1092,14 +1110,7 @@ u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp) | |||
1092 | dev->wireless_handlers = (struct iw_handler_def *)&p80211wext_handler_def; | 1110 | dev->wireless_handlers = (struct iw_handler_def *)&p80211wext_handler_def; |
1093 | #endif | 1111 | #endif |
1094 | 1112 | ||
1095 | dev->open = usbdrv_open; | 1113 | dev->netdev_ops = &otus_netdev_ops; |
1096 | dev->hard_start_xmit = usbdrv_xmit_frame; | ||
1097 | dev->stop = usbdrv_close; | ||
1098 | dev->change_mtu = &usbdrv_change_mtu; | ||
1099 | dev->get_stats = usbdrv_get_stats; | ||
1100 | dev->set_multicast_list = usbdrv_set_multi; | ||
1101 | dev->set_mac_address = usbdrv_set_mac; | ||
1102 | dev->do_ioctl = usbdrv_ioctl; | ||
1103 | 1114 | ||
1104 | dev->flags |= IFF_MULTICAST; | 1115 | dev->flags |= IFF_MULTICAST; |
1105 | 1116 | ||
diff --git a/drivers/staging/otus/zdusb.c b/drivers/staging/otus/zdusb.c index 78f1d2224fa1..2a6d937ba5e8 100644 --- a/drivers/staging/otus/zdusb.c +++ b/drivers/staging/otus/zdusb.c | |||
@@ -48,7 +48,8 @@ static const char driver_name[] = "Otus"; | |||
48 | static struct usb_device_id zd1221_ids [] = { | 48 | static struct usb_device_id zd1221_ids [] = { |
49 | { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) }, | 49 | { USB_DEVICE(VENDOR_ATHR, PRODUCT_AR9170) }, |
50 | { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) }, | 50 | { USB_DEVICE(VENDOR_DLINK, PRODUCT_DWA160A) }, |
51 | { USB_DEVICE(0x0846, 0x9010) }, | 51 | { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WNDA3100) }, |
52 | { USB_DEVICE(VENDOR_NETGEAR, PRODUCT_WN111v2) }, | ||
52 | { } /* Terminating entry */ | 53 | { } /* Terminating entry */ |
53 | }; | 54 | }; |
54 | 55 | ||
diff --git a/drivers/staging/otus/zdusb.h b/drivers/staging/otus/zdusb.h index 656dc212ade5..9f8ab2e96169 100644 --- a/drivers/staging/otus/zdusb.h +++ b/drivers/staging/otus/zdusb.h | |||
@@ -40,4 +40,8 @@ | |||
40 | #define VENDOR_DLINK 0x07D1 //Dlink | 40 | #define VENDOR_DLINK 0x07D1 //Dlink |
41 | #define PRODUCT_DWA160A 0x3C10 | 41 | #define PRODUCT_DWA160A 0x3C10 |
42 | 42 | ||
43 | #define VENDOR_NETGEAR 0x0846 /* NetGear */ | ||
44 | #define PRODUCT_WNDA3100 0x9010 | ||
45 | #define PRODUCT_WN111v2 0x9001 | ||
46 | |||
43 | #endif | 47 | #endif |
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c index 3e67da9ea381..a6eaa42fb669 100644 --- a/drivers/staging/pohmelfs/config.c +++ b/drivers/staging/pohmelfs/config.c | |||
@@ -81,6 +81,45 @@ static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned | |||
81 | return g; | 81 | return g; |
82 | } | 82 | } |
83 | 83 | ||
84 | static inline void pohmelfs_insert_config_entry(struct pohmelfs_sb *psb, struct pohmelfs_config *dst) | ||
85 | { | ||
86 | struct pohmelfs_config *tmp; | ||
87 | |||
88 | INIT_LIST_HEAD(&dst->config_entry); | ||
89 | |||
90 | list_for_each_entry(tmp, &psb->state_list, config_entry) { | ||
91 | if (dst->state.ctl.prio > tmp->state.ctl.prio) | ||
92 | list_add_tail(&dst->config_entry, &tmp->config_entry); | ||
93 | } | ||
94 | if (list_empty(&dst->config_entry)) | ||
95 | list_add_tail(&dst->config_entry, &psb->state_list); | ||
96 | } | ||
97 | |||
98 | static int pohmelfs_move_config_entry(struct pohmelfs_sb *psb, | ||
99 | struct pohmelfs_config *dst, struct pohmelfs_config *new) | ||
100 | { | ||
101 | if ((dst->state.ctl.prio == new->state.ctl.prio) && | ||
102 | (dst->state.ctl.perm == new->state.ctl.perm)) | ||
103 | return 0; | ||
104 | |||
105 | dprintk("%s: dst: prio: %d, perm: %x, new: prio: %d, perm: %d.\n", | ||
106 | __func__, dst->state.ctl.prio, dst->state.ctl.perm, | ||
107 | new->state.ctl.prio, new->state.ctl.perm); | ||
108 | dst->state.ctl.prio = new->state.ctl.prio; | ||
109 | dst->state.ctl.perm = new->state.ctl.perm; | ||
110 | |||
111 | list_del_init(&dst->config_entry); | ||
112 | pohmelfs_insert_config_entry(psb, dst); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * pohmelfs_copy_config() is used to copy new state configs from the | ||
118 | * config group (controlled by the netlink messages) into the superblock. | ||
119 | * This happens either at startup time where no transactions can access | ||
120 | * the list of the configs (and thus list of the network states), or at | ||
121 | * run-time, where it is protected by the psb->state_lock. | ||
122 | */ | ||
84 | int pohmelfs_copy_config(struct pohmelfs_sb *psb) | 123 | int pohmelfs_copy_config(struct pohmelfs_sb *psb) |
85 | { | 124 | { |
86 | struct pohmelfs_config_group *g; | 125 | struct pohmelfs_config_group *g; |
@@ -103,7 +142,9 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb) | |||
103 | err = 0; | 142 | err = 0; |
104 | list_for_each_entry(dst, &psb->state_list, config_entry) { | 143 | list_for_each_entry(dst, &psb->state_list, config_entry) { |
105 | if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) { | 144 | if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) { |
106 | err = -EEXIST; | 145 | err = pohmelfs_move_config_entry(psb, dst, c); |
146 | if (!err) | ||
147 | err = -EEXIST; | ||
107 | break; | 148 | break; |
108 | } | 149 | } |
109 | } | 150 | } |
@@ -119,7 +160,7 @@ int pohmelfs_copy_config(struct pohmelfs_sb *psb) | |||
119 | 160 | ||
120 | memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl)); | 161 | memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl)); |
121 | 162 | ||
122 | list_add_tail(&dst->config_entry, &psb->state_list); | 163 | pohmelfs_insert_config_entry(psb, dst); |
123 | 164 | ||
124 | err = pohmelfs_state_init_one(psb, dst); | 165 | err = pohmelfs_state_init_one(psb, dst); |
125 | if (err) { | 166 | if (err) { |
@@ -248,6 +289,13 @@ out_unlock: | |||
248 | return err; | 289 | return err; |
249 | } | 290 | } |
250 | 291 | ||
292 | static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new) | ||
293 | { | ||
294 | old->perm = new->perm; | ||
295 | old->prio = new->prio; | ||
296 | return 0; | ||
297 | } | ||
298 | |||
251 | static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) | 299 | static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) |
252 | { | 300 | { |
253 | struct pohmelfs_config_group *g; | 301 | struct pohmelfs_config_group *g; |
@@ -278,6 +326,9 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) | |||
278 | g->num_entry--; | 326 | g->num_entry--; |
279 | kfree(c); | 327 | kfree(c); |
280 | goto out_unlock; | 328 | goto out_unlock; |
329 | } else if (action == POHMELFS_FLAGS_MODIFY) { | ||
330 | err = pohmelfs_modify_config(sc, ctl); | ||
331 | goto out_unlock; | ||
281 | } else { | 332 | } else { |
282 | err = -EEXIST; | 333 | err = -EEXIST; |
283 | goto out_unlock; | 334 | goto out_unlock; |
@@ -296,6 +347,7 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action) | |||
296 | } | 347 | } |
297 | memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl)); | 348 | memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl)); |
298 | g->num_entry++; | 349 | g->num_entry++; |
350 | |||
299 | list_add_tail(&c->config_entry, &g->config_list); | 351 | list_add_tail(&c->config_entry, &g->config_list); |
300 | 352 | ||
301 | out_unlock: | 353 | out_unlock: |
@@ -401,10 +453,9 @@ static void pohmelfs_cn_callback(void *data) | |||
401 | 453 | ||
402 | switch (msg->flags) { | 454 | switch (msg->flags) { |
403 | case POHMELFS_FLAGS_ADD: | 455 | case POHMELFS_FLAGS_ADD: |
404 | err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_ADD); | ||
405 | break; | ||
406 | case POHMELFS_FLAGS_DEL: | 456 | case POHMELFS_FLAGS_DEL: |
407 | err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_DEL); | 457 | case POHMELFS_FLAGS_MODIFY: |
458 | err = pohmelfs_cn_ctl(msg, msg->flags); | ||
408 | break; | 459 | break; |
409 | case POHMELFS_FLAGS_SHOW: | 460 | case POHMELFS_FLAGS_SHOW: |
410 | err = pohmelfs_cn_disp(msg); | 461 | err = pohmelfs_cn_disp(msg); |
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c index 7a41183a32e1..b5799842fb84 100644 --- a/drivers/staging/pohmelfs/dir.c +++ b/drivers/staging/pohmelfs/dir.c | |||
@@ -328,7 +328,7 @@ static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi) | |||
328 | { | 328 | { |
329 | struct inode *inode = &pi->vfs_inode; | 329 | struct inode *inode = &pi->vfs_inode; |
330 | struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb); | 330 | struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb); |
331 | long ret = msecs_to_jiffies(25000); | 331 | long ret = psb->wait_on_page_timeout; |
332 | int err; | 332 | int err; |
333 | 333 | ||
334 | dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n", | 334 | dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n", |
@@ -389,11 +389,11 @@ static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
389 | dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n", | 389 | dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n", |
390 | __func__, pi->ino, (u64)file->f_pos, | 390 | __func__, pi->ino, (u64)file->f_pos, |
391 | (unsigned long)file->private_data); | 391 | (unsigned long)file->private_data); |
392 | 392 | #if 0 | |
393 | err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK); | 393 | err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK); |
394 | if (err) | 394 | if (err) |
395 | return err; | 395 | return err; |
396 | 396 | #endif | |
397 | err = pohmelfs_sync_remote_dir(pi); | 397 | err = pohmelfs_sync_remote_dir(pi); |
398 | if (err) | 398 | if (err) |
399 | return err; | 399 | return err; |
@@ -513,10 +513,6 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
513 | 513 | ||
514 | need_lock = pohmelfs_need_lock(parent, lock_type); | 514 | need_lock = pohmelfs_need_lock(parent, lock_type); |
515 | 515 | ||
516 | err = pohmelfs_data_lock(parent, 0, ~0, lock_type); | ||
517 | if (err) | ||
518 | goto out; | ||
519 | |||
520 | str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0); | 516 | str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0); |
521 | 517 | ||
522 | mutex_lock(&parent->offset_lock); | 518 | mutex_lock(&parent->offset_lock); |
@@ -525,8 +521,8 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
525 | ino = n->ino; | 521 | ino = n->ino; |
526 | mutex_unlock(&parent->offset_lock); | 522 | mutex_unlock(&parent->offset_lock); |
527 | 523 | ||
528 | dprintk("%s: 1 ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx.\n", | 524 | dprintk("%s: start ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx, need_lock: %d.\n", |
529 | __func__, ino, inode, str.name, str.hash, parent->state); | 525 | __func__, ino, inode, str.name, str.hash, parent->state, need_lock); |
530 | 526 | ||
531 | if (ino) { | 527 | if (ino) { |
532 | inode = ilookup(dir->i_sb, ino); | 528 | inode = ilookup(dir->i_sb, ino); |
@@ -534,7 +530,7 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
534 | goto out; | 530 | goto out; |
535 | } | 531 | } |
536 | 532 | ||
537 | dprintk("%s: dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n", | 533 | dprintk("%s: no inode dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n", |
538 | __func__, dir, parent->ino, | 534 | __func__, dir, parent->ino, |
539 | str.name, str.len, parent->state, ino); | 535 | str.name, str.len, parent->state, ino); |
540 | 536 | ||
@@ -543,6 +539,10 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
543 | goto out; | 539 | goto out; |
544 | } | 540 | } |
545 | 541 | ||
542 | err = pohmelfs_data_lock(parent, 0, ~0, lock_type); | ||
543 | if (err) | ||
544 | goto out; | ||
545 | |||
546 | err = pohmelfs_lookup_single(parent, &str, ino); | 546 | err = pohmelfs_lookup_single(parent, &str, ino); |
547 | if (err) | 547 | if (err) |
548 | goto out; | 548 | goto out; |
@@ -557,10 +557,10 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct | |||
557 | 557 | ||
558 | if (ino) { | 558 | if (ino) { |
559 | inode = ilookup(dir->i_sb, ino); | 559 | inode = ilookup(dir->i_sb, ino); |
560 | printk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n", | 560 | dprintk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n", |
561 | __func__, ino, inode, str.name, str.hash); | 561 | __func__, ino, inode, str.name, str.hash); |
562 | if (!inode) { | 562 | if (!inode) { |
563 | printk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n", | 563 | dprintk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n", |
564 | __func__, ino, str.name, str.hash); | 564 | __func__, ino, str.name, str.hash); |
565 | //return NULL; | 565 | //return NULL; |
566 | return ERR_PTR(-EACCES); | 566 | return ERR_PTR(-EACCES); |
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index 5bf16504cd6f..b2eaf9047266 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c | |||
@@ -1169,16 +1169,17 @@ err_out_put: | |||
1169 | static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 1169 | static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |
1170 | { | 1170 | { |
1171 | struct inode *inode = dentry->d_inode; | 1171 | struct inode *inode = dentry->d_inode; |
1172 | #if 0 | ||
1172 | struct pohmelfs_inode *pi = POHMELFS_I(inode); | 1173 | struct pohmelfs_inode *pi = POHMELFS_I(inode); |
1173 | int err; | 1174 | int err; |
1174 | 1175 | ||
1175 | err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK); | 1176 | err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK); |
1176 | if (err) | 1177 | if (err) |
1177 | return err; | 1178 | return err; |
1178 | |||
1179 | dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n", | 1179 | dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n", |
1180 | __func__, pi->ino, inode->i_mode, inode->i_uid, | 1180 | __func__, pi->ino, inode->i_mode, inode->i_uid, |
1181 | inode->i_gid, inode->i_size); | 1181 | inode->i_gid, inode->i_size); |
1182 | #endif | ||
1182 | 1183 | ||
1183 | generic_fillattr(inode, stat); | 1184 | generic_fillattr(inode, stat); |
1184 | return 0; | 1185 | return 0; |
@@ -1342,14 +1343,6 @@ static void pohmelfs_put_super(struct super_block *sb) | |||
1342 | 1343 | ||
1343 | kfree(psb); | 1344 | kfree(psb); |
1344 | sb->s_fs_info = NULL; | 1345 | sb->s_fs_info = NULL; |
1345 | |||
1346 | pohmelfs_ftrans_exit(); | ||
1347 | } | ||
1348 | |||
1349 | static int pohmelfs_remount(struct super_block *sb, int *flags, char *data) | ||
1350 | { | ||
1351 | *flags |= MS_RDONLY; | ||
1352 | return 0; | ||
1353 | } | 1346 | } |
1354 | 1347 | ||
1355 | static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 1348 | static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
@@ -1394,42 +1387,33 @@ static int pohmelfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
1394 | return 0; | 1387 | return 0; |
1395 | } | 1388 | } |
1396 | 1389 | ||
1397 | static const struct super_operations pohmelfs_sb_ops = { | ||
1398 | .alloc_inode = pohmelfs_alloc_inode, | ||
1399 | .destroy_inode = pohmelfs_destroy_inode, | ||
1400 | .drop_inode = pohmelfs_drop_inode, | ||
1401 | .write_inode = pohmelfs_write_inode, | ||
1402 | .put_super = pohmelfs_put_super, | ||
1403 | .remount_fs = pohmelfs_remount, | ||
1404 | .statfs = pohmelfs_statfs, | ||
1405 | .show_options = pohmelfs_show_options, | ||
1406 | }; | ||
1407 | |||
1408 | enum { | 1390 | enum { |
1409 | pohmelfs_opt_idx, | 1391 | pohmelfs_opt_idx, |
1392 | pohmelfs_opt_crypto_thread_num, | ||
1393 | pohmelfs_opt_trans_max_pages, | ||
1394 | pohmelfs_opt_crypto_fail_unsupported, | ||
1395 | |||
1396 | /* Remountable options */ | ||
1410 | pohmelfs_opt_trans_scan_timeout, | 1397 | pohmelfs_opt_trans_scan_timeout, |
1411 | pohmelfs_opt_drop_scan_timeout, | 1398 | pohmelfs_opt_drop_scan_timeout, |
1412 | pohmelfs_opt_wait_on_page_timeout, | 1399 | pohmelfs_opt_wait_on_page_timeout, |
1413 | pohmelfs_opt_trans_retries, | 1400 | pohmelfs_opt_trans_retries, |
1414 | pohmelfs_opt_crypto_thread_num, | ||
1415 | pohmelfs_opt_trans_max_pages, | ||
1416 | pohmelfs_opt_crypto_fail_unsupported, | ||
1417 | pohmelfs_opt_mcache_timeout, | 1401 | pohmelfs_opt_mcache_timeout, |
1418 | }; | 1402 | }; |
1419 | 1403 | ||
1420 | static struct match_token pohmelfs_tokens[] = { | 1404 | static struct match_token pohmelfs_tokens[] = { |
1421 | {pohmelfs_opt_idx, "idx=%u"}, | 1405 | {pohmelfs_opt_idx, "idx=%u"}, |
1406 | {pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"}, | ||
1407 | {pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"}, | ||
1408 | {pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"}, | ||
1422 | {pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"}, | 1409 | {pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"}, |
1423 | {pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"}, | 1410 | {pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"}, |
1424 | {pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"}, | 1411 | {pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"}, |
1425 | {pohmelfs_opt_trans_retries, "trans_retries=%u"}, | 1412 | {pohmelfs_opt_trans_retries, "trans_retries=%u"}, |
1426 | {pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"}, | ||
1427 | {pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"}, | ||
1428 | {pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"}, | ||
1429 | {pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"}, | 1413 | {pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"}, |
1430 | }; | 1414 | }; |
1431 | 1415 | ||
1432 | static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb) | 1416 | static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb, int remount) |
1433 | { | 1417 | { |
1434 | char *p; | 1418 | char *p; |
1435 | substring_t args[MAX_OPT_ARGS]; | 1419 | substring_t args[MAX_OPT_ARGS]; |
@@ -1449,6 +1433,9 @@ static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb) | |||
1449 | if (err) | 1433 | if (err) |
1450 | return err; | 1434 | return err; |
1451 | 1435 | ||
1436 | if (remount && token <= pohmelfs_opt_crypto_fail_unsupported) | ||
1437 | continue; | ||
1438 | |||
1452 | switch (token) { | 1439 | switch (token) { |
1453 | case pohmelfs_opt_idx: | 1440 | case pohmelfs_opt_idx: |
1454 | psb->idx = option; | 1441 | psb->idx = option; |
@@ -1485,6 +1472,25 @@ static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb) | |||
1485 | return 0; | 1472 | return 0; |
1486 | } | 1473 | } |
1487 | 1474 | ||
1475 | static int pohmelfs_remount(struct super_block *sb, int *flags, char *data) | ||
1476 | { | ||
1477 | int err; | ||
1478 | struct pohmelfs_sb *psb = POHMELFS_SB(sb); | ||
1479 | unsigned long old_sb_flags = sb->s_flags; | ||
1480 | |||
1481 | err = pohmelfs_parse_options(data, psb, 1); | ||
1482 | if (err) | ||
1483 | goto err_out_restore; | ||
1484 | |||
1485 | if (!(*flags & MS_RDONLY)) | ||
1486 | sb->s_flags &= ~MS_RDONLY; | ||
1487 | return 0; | ||
1488 | |||
1489 | err_out_restore: | ||
1490 | sb->s_flags = old_sb_flags; | ||
1491 | return err; | ||
1492 | } | ||
1493 | |||
1488 | static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count) | 1494 | static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count) |
1489 | { | 1495 | { |
1490 | struct inode *inode = &pi->vfs_inode; | 1496 | struct inode *inode = &pi->vfs_inode; |
@@ -1753,6 +1759,57 @@ err_out_exit: | |||
1753 | return err; | 1759 | return err; |
1754 | } | 1760 | } |
1755 | 1761 | ||
1762 | static int pohmelfs_show_stats(struct seq_file *m, struct vfsmount *mnt) | ||
1763 | { | ||
1764 | struct netfs_state *st; | ||
1765 | struct pohmelfs_ctl *ctl; | ||
1766 | struct pohmelfs_sb *psb = POHMELFS_SB(mnt->mnt_sb); | ||
1767 | struct pohmelfs_config *c; | ||
1768 | |||
1769 | mutex_lock(&psb->state_lock); | ||
1770 | |||
1771 | seq_printf(m, "\nidx addr(:port) socket_type protocol active priority permissions\n"); | ||
1772 | |||
1773 | list_for_each_entry(c, &psb->state_list, config_entry) { | ||
1774 | st = &c->state; | ||
1775 | ctl = &st->ctl; | ||
1776 | |||
1777 | seq_printf(m, "%u ", ctl->idx); | ||
1778 | if (ctl->addr.sa_family == AF_INET) { | ||
1779 | struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr; | ||
1780 | //seq_printf(m, "%pi4:%u", &sin->sin_addr.s_addr, ntohs(sin->sin_port)); | ||
1781 | seq_printf(m, "%u.%u.%u.%u:%u", NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port)); | ||
1782 | } else if (ctl->addr.sa_family == AF_INET6) { | ||
1783 | struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr; | ||
1784 | seq_printf(m, "%pi6:%u", &sin->sin6_addr, ntohs(sin->sin6_port)); | ||
1785 | } else { | ||
1786 | unsigned int i; | ||
1787 | for (i=0; i<ctl->addrlen; ++i) | ||
1788 | seq_printf(m, "%02x.", ctl->addr.addr[i]); | ||
1789 | } | ||
1790 | |||
1791 | seq_printf(m, " %u %u %d %u %x\n", | ||
1792 | ctl->type, ctl->proto, | ||
1793 | st->socket != NULL, | ||
1794 | ctl->prio, ctl->perm); | ||
1795 | } | ||
1796 | mutex_unlock(&psb->state_lock); | ||
1797 | |||
1798 | return 0; | ||
1799 | } | ||
1800 | |||
1801 | static const struct super_operations pohmelfs_sb_ops = { | ||
1802 | .alloc_inode = pohmelfs_alloc_inode, | ||
1803 | .destroy_inode = pohmelfs_destroy_inode, | ||
1804 | .drop_inode = pohmelfs_drop_inode, | ||
1805 | .write_inode = pohmelfs_write_inode, | ||
1806 | .put_super = pohmelfs_put_super, | ||
1807 | .remount_fs = pohmelfs_remount, | ||
1808 | .statfs = pohmelfs_statfs, | ||
1809 | .show_options = pohmelfs_show_options, | ||
1810 | .show_stats = pohmelfs_show_stats, | ||
1811 | }; | ||
1812 | |||
1756 | /* | 1813 | /* |
1757 | * Allocate private superblock and create root dir. | 1814 | * Allocate private superblock and create root dir. |
1758 | */ | 1815 | */ |
@@ -1764,8 +1821,6 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) | |||
1764 | struct pohmelfs_inode *npi; | 1821 | struct pohmelfs_inode *npi; |
1765 | struct qstr str; | 1822 | struct qstr str; |
1766 | 1823 | ||
1767 | pohmelfs_ftrans_init(); | ||
1768 | |||
1769 | psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL); | 1824 | psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL); |
1770 | if (!psb) | 1825 | if (!psb) |
1771 | goto err_out_exit; | 1826 | goto err_out_exit; |
@@ -1816,7 +1871,7 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) | |||
1816 | mutex_init(&psb->state_lock); | 1871 | mutex_init(&psb->state_lock); |
1817 | INIT_LIST_HEAD(&psb->state_list); | 1872 | INIT_LIST_HEAD(&psb->state_list); |
1818 | 1873 | ||
1819 | err = pohmelfs_parse_options((char *) data, psb); | 1874 | err = pohmelfs_parse_options((char *) data, psb, 0); |
1820 | if (err) | 1875 | if (err) |
1821 | goto err_out_free_sb; | 1876 | goto err_out_free_sb; |
1822 | 1877 | ||
@@ -1845,6 +1900,8 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent) | |||
1845 | err = PTR_ERR(npi); | 1900 | err = PTR_ERR(npi); |
1846 | goto err_out_crypto_exit; | 1901 | goto err_out_crypto_exit; |
1847 | } | 1902 | } |
1903 | set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state); | ||
1904 | clear_bit(NETFS_INODE_OWNED, &npi->state); | ||
1848 | 1905 | ||
1849 | root = &npi->vfs_inode; | 1906 | root = &npi->vfs_inode; |
1850 | 1907 | ||
@@ -1887,11 +1944,29 @@ static int pohmelfs_get_sb(struct file_system_type *fs_type, | |||
1887 | mnt); | 1944 | mnt); |
1888 | } | 1945 | } |
1889 | 1946 | ||
1947 | /* | ||
1948 | * We need this to sync all inodes earlier, since when writeback | ||
1949 | * is invoked from the umount/mntput path dcache is already shrunk, | ||
1950 | * see generic_shutdown_super(), and no inodes can access the path. | ||
1951 | */ | ||
1952 | static void pohmelfs_kill_super(struct super_block *sb) | ||
1953 | { | ||
1954 | struct writeback_control wbc = { | ||
1955 | .sync_mode = WB_SYNC_ALL, | ||
1956 | .range_start = 0, | ||
1957 | .range_end = LLONG_MAX, | ||
1958 | .nr_to_write = LONG_MAX, | ||
1959 | }; | ||
1960 | generic_sync_sb_inodes(sb, &wbc); | ||
1961 | |||
1962 | kill_anon_super(sb); | ||
1963 | } | ||
1964 | |||
1890 | static struct file_system_type pohmel_fs_type = { | 1965 | static struct file_system_type pohmel_fs_type = { |
1891 | .owner = THIS_MODULE, | 1966 | .owner = THIS_MODULE, |
1892 | .name = "pohmel", | 1967 | .name = "pohmel", |
1893 | .get_sb = pohmelfs_get_sb, | 1968 | .get_sb = pohmelfs_get_sb, |
1894 | .kill_sb = kill_anon_super, | 1969 | .kill_sb = pohmelfs_kill_super, |
1895 | }; | 1970 | }; |
1896 | 1971 | ||
1897 | /* | 1972 | /* |
diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c index ad4a18559bdd..22fef18cae90 100644 --- a/drivers/staging/pohmelfs/lock.c +++ b/drivers/staging/pohmelfs/lock.c | |||
@@ -41,7 +41,8 @@ static int pohmelfs_send_lock_trans(struct pohmelfs_inode *pi, | |||
41 | path_len = err; | 41 | path_len = err; |
42 | 42 | ||
43 | err = -ENOMEM; | 43 | err = -ENOMEM; |
44 | t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize, 0, 0); | 44 | t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize, |
45 | NETFS_TRANS_SINGLE_DST, 0); | ||
45 | if (!t) | 46 | if (!t) |
46 | goto err_out_exit; | 47 | goto err_out_exit; |
47 | 48 | ||
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c index c9b8540c1efe..11ecac026ca7 100644 --- a/drivers/staging/pohmelfs/net.c +++ b/drivers/staging/pohmelfs/net.c | |||
@@ -26,55 +26,6 @@ | |||
26 | 26 | ||
27 | #include "netfs.h" | 27 | #include "netfs.h" |
28 | 28 | ||
29 | static int pohmelfs_ftrans_size = 10240; | ||
30 | static u32 *pohmelfs_ftrans; | ||
31 | |||
32 | int pohmelfs_ftrans_init(void) | ||
33 | { | ||
34 | pohmelfs_ftrans = vmalloc(pohmelfs_ftrans_size * 4); | ||
35 | if (!pohmelfs_ftrans) | ||
36 | return -ENOMEM; | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | void pohmelfs_ftrans_exit(void) | ||
42 | { | ||
43 | vfree(pohmelfs_ftrans); | ||
44 | } | ||
45 | |||
46 | void pohmelfs_ftrans_clean(u64 id) | ||
47 | { | ||
48 | if (pohmelfs_ftrans) { | ||
49 | u32 i = id & 0xffffffff; | ||
50 | int idx = i % pohmelfs_ftrans_size; | ||
51 | |||
52 | pohmelfs_ftrans[idx] = 0; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | void pohmelfs_ftrans_update(u64 id) | ||
57 | { | ||
58 | if (pohmelfs_ftrans) { | ||
59 | u32 i = id & 0xffffffff; | ||
60 | int idx = i % pohmelfs_ftrans_size; | ||
61 | |||
62 | pohmelfs_ftrans[idx] = i; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | int pohmelfs_ftrans_check(u64 id) | ||
67 | { | ||
68 | if (pohmelfs_ftrans) { | ||
69 | u32 i = id & 0xffffffff; | ||
70 | int idx = i % pohmelfs_ftrans_size; | ||
71 | |||
72 | return (pohmelfs_ftrans[idx] == i); | ||
73 | } | ||
74 | |||
75 | return -1; | ||
76 | } | ||
77 | |||
78 | /* | 29 | /* |
79 | * Async machinery lives here. | 30 | * Async machinery lives here. |
80 | * All commands being sent to server do _not_ require sync reply, | 31 | * All commands being sent to server do _not_ require sync reply, |
@@ -450,8 +401,24 @@ static int pohmelfs_readdir_response(struct netfs_state *st) | |||
450 | if (err != -EEXIST) | 401 | if (err != -EEXIST) |
451 | goto err_out_put; | 402 | goto err_out_put; |
452 | } else { | 403 | } else { |
404 | struct dentry *dentry, *alias, *pd; | ||
405 | |||
453 | set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state); | 406 | set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state); |
454 | clear_bit(NETFS_INODE_OWNED, &npi->state); | 407 | clear_bit(NETFS_INODE_OWNED, &npi->state); |
408 | |||
409 | pd = d_find_alias(&parent->vfs_inode); | ||
410 | if (pd) { | ||
411 | str.hash = full_name_hash(str.name, str.len); | ||
412 | dentry = d_alloc(pd, &str); | ||
413 | if (dentry) { | ||
414 | alias = d_materialise_unique(dentry, &npi->vfs_inode); | ||
415 | if (alias) | ||
416 | dput(dentry); | ||
417 | } | ||
418 | |||
419 | dput(dentry); | ||
420 | dput(pd); | ||
421 | } | ||
455 | } | 422 | } |
456 | } | 423 | } |
457 | out: | 424 | out: |
@@ -638,15 +605,12 @@ static int pohmelfs_transaction_response(struct netfs_state *st) | |||
638 | if (dst) { | 605 | if (dst) { |
639 | netfs_trans_remove_nolock(dst, st); | 606 | netfs_trans_remove_nolock(dst, st); |
640 | t = dst->trans; | 607 | t = dst->trans; |
641 | |||
642 | pohmelfs_ftrans_update(cmd->start); | ||
643 | } | 608 | } |
644 | mutex_unlock(&st->trans_lock); | 609 | mutex_unlock(&st->trans_lock); |
645 | 610 | ||
646 | if (!t) { | 611 | if (!t) { |
647 | int check = pohmelfs_ftrans_check(cmd->start); | 612 | printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u.\n", |
648 | printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u, double: %d.\n", | 613 | __func__, cmd->start, cmd->id, cmd->size, cmd->ext); |
649 | __func__, cmd->start, cmd->id, cmd->size, cmd->ext, check); | ||
650 | err = -EINVAL; | 614 | err = -EINVAL; |
651 | goto out; | 615 | goto out; |
652 | } | 616 | } |
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h index 2ff21ae5bb12..c78cfcb042fb 100644 --- a/drivers/staging/pohmelfs/netfs.h +++ b/drivers/staging/pohmelfs/netfs.h | |||
@@ -87,6 +87,7 @@ enum { | |||
87 | POHMELFS_FLAGS_DEL, /* Network state control message for DEL */ | 87 | POHMELFS_FLAGS_DEL, /* Network state control message for DEL */ |
88 | POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */ | 88 | POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */ |
89 | POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */ | 89 | POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */ |
90 | POHMELFS_FLAGS_MODIFY, /* Network state modification message */ | ||
90 | }; | 91 | }; |
91 | 92 | ||
92 | /* | 93 | /* |
@@ -116,16 +117,20 @@ struct pohmelfs_crypto | |||
116 | unsigned char data[0]; /* Algorithm string, key and IV */ | 117 | unsigned char data[0]; /* Algorithm string, key and IV */ |
117 | }; | 118 | }; |
118 | 119 | ||
120 | #define POHMELFS_IO_PERM_READ (1<<0) | ||
121 | #define POHMELFS_IO_PERM_WRITE (1<<1) | ||
122 | |||
119 | /* | 123 | /* |
120 | * Configuration command used to create table of different remote servers. | 124 | * Configuration command used to create table of different remote servers. |
121 | */ | 125 | */ |
122 | struct pohmelfs_ctl | 126 | struct pohmelfs_ctl |
123 | { | 127 | { |
124 | unsigned int idx; /* Config index */ | 128 | __u32 idx; /* Config index */ |
125 | unsigned int type; /* Socket type */ | 129 | __u32 type; /* Socket type */ |
126 | unsigned int proto; /* Socket protocol */ | 130 | __u32 proto; /* Socket protocol */ |
127 | unsigned int addrlen; /* Size of the address */ | 131 | __u16 addrlen; /* Size of the address */ |
128 | unsigned short unused; /* Align structure by 4 bytes */ | 132 | __u16 perm; /* IO permission */ |
133 | __u16 prio; /* IO priority */ | ||
129 | struct saddr addr; /* Remote server address */ | 134 | struct saddr addr; /* Remote server address */ |
130 | }; | 135 | }; |
131 | 136 | ||
@@ -921,12 +926,6 @@ static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb, | |||
921 | pohmelfs_mcache_free(psb, m); | 926 | pohmelfs_mcache_free(psb, m); |
922 | } | 927 | } |
923 | 928 | ||
924 | int pohmelfs_ftrans_init(void); | ||
925 | void pohmelfs_ftrans_exit(void); | ||
926 | void pohmelfs_ftrans_update(u64 id); | ||
927 | int pohmelfs_ftrans_check(u64 id); | ||
928 | void pohmelfs_ftrans_clean(u64 id); | ||
929 | |||
930 | #endif /* __KERNEL__*/ | 929 | #endif /* __KERNEL__*/ |
931 | 930 | ||
932 | #endif /* __NETFS_H */ | 931 | #endif /* __NETFS_H */ |
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c index bcb59425a21c..fef5f9bd6920 100644 --- a/drivers/staging/pohmelfs/trans.c +++ b/drivers/staging/pohmelfs/trans.c | |||
@@ -456,34 +456,25 @@ int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb) | |||
456 | __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state); | 456 | __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state); |
457 | #endif | 457 | #endif |
458 | mutex_lock(&psb->state_lock); | 458 | mutex_lock(&psb->state_lock); |
459 | list_for_each_entry(c, &psb->state_list, config_entry) { | ||
460 | st = &c->state; | ||
459 | 461 | ||
460 | if ((t->flags & NETFS_TRANS_SINGLE_DST) && psb->active_state) { | 462 | if (t->flags & NETFS_TRANS_SINGLE_DST) { |
461 | st = &psb->active_state->state; | 463 | if (!(st->ctl.perm & POHMELFS_IO_PERM_READ)) |
462 | 464 | continue; | |
463 | err = -EPIPE; | 465 | } else { |
464 | if (netfs_state_poll(st) & POLLOUT) { | 466 | if (!(st->ctl.perm & POHMELFS_IO_PERM_WRITE)) |
465 | err = netfs_trans_push_dst(t, st); | 467 | continue; |
466 | if (!err) { | ||
467 | err = netfs_trans_send(t, st); | ||
468 | if (err) { | ||
469 | netfs_trans_drop_last(t, st); | ||
470 | } else { | ||
471 | pohmelfs_switch_active(psb); | ||
472 | goto out; | ||
473 | } | ||
474 | } | ||
475 | } | 468 | } |
476 | pohmelfs_switch_active(psb); | ||
477 | } | ||
478 | 469 | ||
479 | list_for_each_entry(c, &psb->state_list, config_entry) { | 470 | if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio)) |
480 | st = &c->state; | 471 | st = &psb->active_state->state; |
481 | 472 | ||
482 | err = netfs_trans_push(t, st); | 473 | err = netfs_trans_push(t, st); |
483 | if (!err && (t->flags & NETFS_TRANS_SINGLE_DST)) | 474 | if (!err && (t->flags & NETFS_TRANS_SINGLE_DST)) |
484 | break; | 475 | break; |
485 | } | 476 | } |
486 | out: | 477 | |
487 | mutex_unlock(&psb->state_lock); | 478 | mutex_unlock(&psb->state_lock); |
488 | #if 0 | 479 | #if 0 |
489 | dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n", | 480 | dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n", |
@@ -501,8 +492,6 @@ int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb) | |||
501 | 492 | ||
502 | t->gen = atomic_inc_return(&psb->trans_gen); | 493 | t->gen = atomic_inc_return(&psb->trans_gen); |
503 | 494 | ||
504 | pohmelfs_ftrans_clean(t->gen); | ||
505 | |||
506 | cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) + | 495 | cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) + |
507 | t->attached_size + t->attached_pages * sizeof(struct netfs_cmd); | 496 | t->attached_size + t->attached_pages * sizeof(struct netfs_cmd); |
508 | cmd->cmd = NETFS_TRANS; | 497 | cmd->cmd = NETFS_TRANS; |
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c index cf17bcdd7333..6c4396f0903b 100644 --- a/drivers/staging/rt2860/rt_main_dev.c +++ b/drivers/staging/rt2860/rt_main_dev.c | |||
@@ -722,6 +722,20 @@ err: | |||
722 | return (-1); | 722 | return (-1); |
723 | } /* End of rt28xx_open */ | 723 | } /* End of rt28xx_open */ |
724 | 724 | ||
725 | static const struct net_device_ops rt2860_netdev_ops = { | ||
726 | .ndo_open = MainVirtualIF_open, | ||
727 | .ndo_stop = MainVirtualIF_close, | ||
728 | .ndo_do_ioctl = rt28xx_ioctl, | ||
729 | .ndo_get_stats = RT28xx_get_ether_stats, | ||
730 | .ndo_validate_addr = NULL, | ||
731 | .ndo_set_mac_address = eth_mac_addr, | ||
732 | .ndo_change_mtu = eth_change_mtu, | ||
733 | #ifdef IKANOS_VX_1X0 | ||
734 | .ndo_start_xmit = IKANOS_DataFramesTx, | ||
735 | #else | ||
736 | .ndo_start_xmit = rt28xx_send_packets, | ||
737 | #endif | ||
738 | }; | ||
725 | 739 | ||
726 | /* Must not be called for mdev and apdev */ | 740 | /* Must not be called for mdev and apdev */ |
727 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) | 741 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) |
@@ -733,11 +747,6 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
733 | 747 | ||
734 | 748 | ||
735 | //ether_setup(dev); | 749 | //ether_setup(dev); |
736 | dev->hard_start_xmit = rt28xx_send_packets; | ||
737 | |||
738 | #ifdef IKANOS_VX_1X0 | ||
739 | dev->hard_start_xmit = IKANOS_DataFramesTx; | ||
740 | #endif // IKANOS_VX_1X0 // | ||
741 | 750 | ||
742 | #ifdef CONFIG_STA_SUPPORT | 751 | #ifdef CONFIG_STA_SUPPORT |
743 | #if WIRELESS_EXT >= 12 | 752 | #if WIRELESS_EXT >= 12 |
@@ -760,12 +769,8 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
760 | #if WIRELESS_EXT < 21 | 769 | #if WIRELESS_EXT < 21 |
761 | dev->get_wireless_stats = rt28xx_get_wireless_stats; | 770 | dev->get_wireless_stats = rt28xx_get_wireless_stats; |
762 | #endif | 771 | #endif |
763 | dev->get_stats = RT28xx_get_ether_stats; | ||
764 | dev->open = MainVirtualIF_open; //rt28xx_open; | ||
765 | dev->stop = MainVirtualIF_close; //rt28xx_close; | ||
766 | dev->priv_flags = INT_MAIN; | 772 | dev->priv_flags = INT_MAIN; |
767 | dev->do_ioctl = rt28xx_ioctl; | 773 | dev->netdev_ops = &rt2860_netdev_ops; |
768 | dev->validate_addr = NULL; | ||
769 | // find available device name | 774 | // find available device name |
770 | for (i = 0; i < 8; i++) | 775 | for (i = 0; i < 8; i++) |
771 | { | 776 | { |
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h index 5dd15aac9ce7..a42caa370808 100644 --- a/drivers/staging/rt2870/rt2870.h +++ b/drivers/staging/rt2870/rt2870.h | |||
@@ -96,6 +96,7 @@ | |||
96 | {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ \ | 96 | {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ \ |
97 | {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \ | 97 | {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \ |
98 | {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \ | 98 | {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \ |
99 | {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */ \ | ||
99 | {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \ | 100 | {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \ |
100 | {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \ | 101 | {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \ |
101 | {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \ | 102 | {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \ |
diff --git a/drivers/staging/rt2870/rt_main_dev.c b/drivers/staging/rt2870/rt_main_dev.c index 313ecea0bfa8..48ad41136d0f 100644 --- a/drivers/staging/rt2870/rt_main_dev.c +++ b/drivers/staging/rt2870/rt_main_dev.c | |||
@@ -855,6 +855,20 @@ err: | |||
855 | return (-1); | 855 | return (-1); |
856 | } /* End of rt28xx_open */ | 856 | } /* End of rt28xx_open */ |
857 | 857 | ||
858 | static const struct net_device_ops rt2870_netdev_ops = { | ||
859 | .ndo_open = MainVirtualIF_open, | ||
860 | .ndo_stop = MainVirtualIF_close, | ||
861 | .ndo_do_ioctl = rt28xx_ioctl, | ||
862 | .ndo_get_stats = RT28xx_get_ether_stats, | ||
863 | .ndo_validate_addr = NULL, | ||
864 | .ndo_set_mac_address = eth_mac_addr, | ||
865 | .ndo_change_mtu = eth_change_mtu, | ||
866 | #ifdef IKANOS_VX_1X0 | ||
867 | .ndo_start_xmit = IKANOS_DataFramesTx, | ||
868 | #else | ||
869 | .ndo_start_xmit = rt28xx_send_packets, | ||
870 | #endif | ||
871 | }; | ||
858 | 872 | ||
859 | /* Must not be called for mdev and apdev */ | 873 | /* Must not be called for mdev and apdev */ |
860 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) | 874 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) |
@@ -866,12 +880,6 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
866 | 880 | ||
867 | 881 | ||
868 | //ether_setup(dev); | 882 | //ether_setup(dev); |
869 | dev->hard_start_xmit = rt28xx_send_packets; | ||
870 | |||
871 | #ifdef IKANOS_VX_1X0 | ||
872 | dev->hard_start_xmit = IKANOS_DataFramesTx; | ||
873 | #endif // IKANOS_VX_1X0 // | ||
874 | |||
875 | // dev->set_multicast_list = ieee80211_set_multicast_list; | 883 | // dev->set_multicast_list = ieee80211_set_multicast_list; |
876 | // dev->change_mtu = ieee80211_change_mtu; | 884 | // dev->change_mtu = ieee80211_change_mtu; |
877 | #ifdef CONFIG_STA_SUPPORT | 885 | #ifdef CONFIG_STA_SUPPORT |
@@ -895,16 +903,10 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
895 | #if WIRELESS_EXT < 21 | 903 | #if WIRELESS_EXT < 21 |
896 | dev->get_wireless_stats = rt28xx_get_wireless_stats; | 904 | dev->get_wireless_stats = rt28xx_get_wireless_stats; |
897 | #endif | 905 | #endif |
898 | dev->get_stats = RT28xx_get_ether_stats; | ||
899 | dev->open = MainVirtualIF_open; //rt28xx_open; | ||
900 | dev->stop = MainVirtualIF_close; //rt28xx_close; | ||
901 | // dev->uninit = ieee80211_if_reinit; | 906 | // dev->uninit = ieee80211_if_reinit; |
902 | // dev->destructor = ieee80211_if_free; | 907 | // dev->destructor = ieee80211_if_free; |
903 | dev->priv_flags = INT_MAIN; | 908 | dev->priv_flags = INT_MAIN; |
904 | dev->do_ioctl = rt28xx_ioctl; | 909 | dev->netdev_ops = &rt2870_netdev_ops; |
905 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) | ||
906 | dev->validate_addr = NULL; | ||
907 | #endif | ||
908 | // find available device name | 910 | // find available device name |
909 | for (i = 0; i < 8; i++) | 911 | for (i = 0; i < 8; i++) |
910 | { | 912 | { |
diff --git a/drivers/staging/rt3070/rt_main_dev.c b/drivers/staging/rt3070/rt_main_dev.c index c000646286e6..81f769cf1096 100644 --- a/drivers/staging/rt3070/rt_main_dev.c +++ b/drivers/staging/rt3070/rt_main_dev.c | |||
@@ -436,7 +436,6 @@ static int rt28xx_init(IN struct net_device *net_dev) | |||
436 | // OID_SET_HT_PHYMODE SetHT; | 436 | // OID_SET_HT_PHYMODE SetHT; |
437 | // WPDMA_GLO_CFG_STRUC GloCfg; | 437 | // WPDMA_GLO_CFG_STRUC GloCfg; |
438 | UINT32 MacCsr0 = 0; | 438 | UINT32 MacCsr0 = 0; |
439 | UINT32 MacValue = 0; | ||
440 | 439 | ||
441 | #ifdef RT2870 | 440 | #ifdef RT2870 |
442 | #ifdef INF_AMAZON_SE | 441 | #ifdef INF_AMAZON_SE |
@@ -849,6 +848,20 @@ err: | |||
849 | return (-1); | 848 | return (-1); |
850 | } /* End of rt28xx_open */ | 849 | } /* End of rt28xx_open */ |
851 | 850 | ||
851 | static const struct net_device_ops rt3070_netdev_ops = { | ||
852 | .ndo_open = MainVirtualIF_open, | ||
853 | .ndo_stop = MainVirtualIF_close, | ||
854 | .ndo_do_ioctl = rt28xx_ioctl, | ||
855 | .ndo_get_stats = RT28xx_get_ether_stats, | ||
856 | .ndo_validate_addr = NULL, | ||
857 | .ndo_set_mac_address = eth_mac_addr, | ||
858 | .ndo_change_mtu = eth_change_mtu, | ||
859 | #ifdef IKANOS_VX_1X0 | ||
860 | .ndo_start_xmit = IKANOS_DataFramesTx, | ||
861 | #else | ||
862 | .ndo_start_xmit = rt28xx_send_packets, | ||
863 | #endif | ||
864 | }; | ||
852 | 865 | ||
853 | /* Must not be called for mdev and apdev */ | 866 | /* Must not be called for mdev and apdev */ |
854 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) | 867 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) |
@@ -860,12 +873,6 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
860 | 873 | ||
861 | 874 | ||
862 | //ether_setup(dev); | 875 | //ether_setup(dev); |
863 | dev->hard_start_xmit = rt28xx_send_packets; | ||
864 | |||
865 | #ifdef IKANOS_VX_1X0 | ||
866 | dev->hard_start_xmit = IKANOS_DataFramesTx; | ||
867 | #endif // IKANOS_VX_1X0 // | ||
868 | |||
869 | // dev->set_multicast_list = ieee80211_set_multicast_list; | 876 | // dev->set_multicast_list = ieee80211_set_multicast_list; |
870 | // dev->change_mtu = ieee80211_change_mtu; | 877 | // dev->change_mtu = ieee80211_change_mtu; |
871 | #ifdef CONFIG_STA_SUPPORT | 878 | #ifdef CONFIG_STA_SUPPORT |
@@ -889,16 +896,10 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p | |||
889 | #if WIRELESS_EXT < 21 | 896 | #if WIRELESS_EXT < 21 |
890 | dev->get_wireless_stats = rt28xx_get_wireless_stats; | 897 | dev->get_wireless_stats = rt28xx_get_wireless_stats; |
891 | #endif | 898 | #endif |
892 | dev->get_stats = RT28xx_get_ether_stats; | ||
893 | dev->open = MainVirtualIF_open; //rt28xx_open; | ||
894 | dev->stop = MainVirtualIF_close; //rt28xx_close; | ||
895 | // dev->uninit = ieee80211_if_reinit; | 899 | // dev->uninit = ieee80211_if_reinit; |
896 | // dev->destructor = ieee80211_if_free; | 900 | // dev->destructor = ieee80211_if_free; |
897 | dev->priv_flags = INT_MAIN; | 901 | dev->priv_flags = INT_MAIN; |
898 | dev->do_ioctl = rt28xx_ioctl; | 902 | dev->netdev_ops = &rt3070_netdev_ops; |
899 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) | ||
900 | dev->validate_addr = NULL; | ||
901 | #endif | ||
902 | // find available device name | 903 | // find available device name |
903 | for (i = 0; i < 8; i++) | 904 | for (i = 0; i < 8; i++) |
904 | { | 905 | { |
diff --git a/drivers/staging/slicoss/README b/drivers/staging/slicoss/README index 2d5b1127ce51..70f49099c065 100644 --- a/drivers/staging/slicoss/README +++ b/drivers/staging/slicoss/README | |||
@@ -10,7 +10,36 @@ TODO: | |||
10 | - move firmware loading to request_firmware() | 10 | - move firmware loading to request_firmware() |
11 | - remove direct memory access of structures | 11 | - remove direct memory access of structures |
12 | - any remaining sparse and checkpatch.pl warnings | 12 | - any remaining sparse and checkpatch.pl warnings |
13 | - any netdev recommended changes | 13 | |
14 | - use net_device_ops | ||
15 | - use dev->stats rather than adapter->stats | ||
16 | - don't cast netdev_priv it is already void | ||
17 | - use compare_ether_addr | ||
18 | - GET RID OF MACROS | ||
19 | - work on all architectures | ||
20 | - without CONFIG_X86_64 confusion | ||
21 | - do 64 bit correctly | ||
22 | - don't depend on order of union | ||
23 | - get rid of ASSERT(), use BUG() instead but only where necessary | ||
24 | looks like most aren't really useful | ||
25 | - no new SIOCDEVPRIVATE ioctl allowed | ||
26 | - don't use module_param for configuring interrupt mitigation | ||
27 | use ethtool instead | ||
28 | - reorder code to elminate use of forward declarations | ||
29 | - don't keep private linked list of drivers. | ||
30 | - remove all the gratiutous debug infrastructure | ||
31 | - use PCI_DEVICE() | ||
32 | - do ethtool correctly using ethtool_ops | ||
33 | - NAPI? | ||
34 | - wasted overhead of extra stats | ||
35 | - state variables for things that are | ||
36 | easily availble and shouldn't be kept in card structure, cardnum, ... | ||
37 | slotnumber, events, ... | ||
38 | - get rid of slic_spinlock wrapper | ||
39 | - volatile == bad design => bad code | ||
40 | - locking too fine grained, not designed just throw more locks | ||
41 | at problem | ||
42 | |||
14 | 43 | ||
15 | Please send patches to: | 44 | Please send patches to: |
16 | Greg Kroah-Hartman <gregkh@suse.de> | 45 | Greg Kroah-Hartman <gregkh@suse.de> |
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 948156348478..6f5d0bff4358 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c | |||
@@ -345,6 +345,19 @@ static void slic_init_adapter(struct net_device *netdev, | |||
345 | return; | 345 | return; |
346 | } | 346 | } |
347 | 347 | ||
348 | static const struct net_device_ops slic_netdev_ops = { | ||
349 | .ndo_open = slic_entry_open, | ||
350 | .ndo_stop = slic_entry_halt, | ||
351 | .ndo_start_xmit = slic_xmit_start, | ||
352 | .ndo_do_ioctl = slic_ioctl, | ||
353 | .ndo_set_mac_address = slic_mac_set_address, | ||
354 | .ndo_get_stats = slic_get_stats, | ||
355 | .ndo_set_multicast_list = slic_mcast_set_list, | ||
356 | .ndo_validate_addr = eth_validate_addr, | ||
357 | .ndo_set_mac_address = eth_mac_addr, | ||
358 | .ndo_change_mtu = eth_change_mtu, | ||
359 | }; | ||
360 | |||
348 | static int __devinit slic_entry_probe(struct pci_dev *pcidev, | 361 | static int __devinit slic_entry_probe(struct pci_dev *pcidev, |
349 | const struct pci_device_id *pci_tbl_entry) | 362 | const struct pci_device_id *pci_tbl_entry) |
350 | { | 363 | { |
@@ -442,13 +455,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev, | |||
442 | 455 | ||
443 | netdev->base_addr = (unsigned long)adapter->memorybase; | 456 | netdev->base_addr = (unsigned long)adapter->memorybase; |
444 | netdev->irq = adapter->irq; | 457 | netdev->irq = adapter->irq; |
445 | netdev->open = slic_entry_open; | 458 | netdev->netdev_ops = &slic_netdev_ops; |
446 | netdev->stop = slic_entry_halt; | ||
447 | netdev->hard_start_xmit = slic_xmit_start; | ||
448 | netdev->do_ioctl = slic_ioctl; | ||
449 | netdev->set_mac_address = slic_mac_set_address; | ||
450 | netdev->get_stats = slic_get_stats; | ||
451 | netdev->set_multicast_list = slic_mcast_set_list; | ||
452 | 459 | ||
453 | slic_debug_adapter_create(adapter); | 460 | slic_debug_adapter_create(adapter); |
454 | 461 | ||
@@ -1260,7 +1267,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address) | |||
1260 | } | 1267 | } |
1261 | 1268 | ||
1262 | /* Doesn't already exist. Allocate a structure to hold it */ | 1269 | /* Doesn't already exist. Allocate a structure to hold it */ |
1263 | mcaddr = kmalloc(sizeof(struct mcast_address), GFP_KERNEL); | 1270 | mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC); |
1264 | if (mcaddr == NULL) | 1271 | if (mcaddr == NULL) |
1265 | return 1; | 1272 | return 1; |
1266 | 1273 | ||
@@ -2284,7 +2291,7 @@ static u32 slic_card_locate(struct adapter *adapter) | |||
2284 | } | 2291 | } |
2285 | if (!physcard) { | 2292 | if (!physcard) { |
2286 | /* no structure allocated for this physical card yet */ | 2293 | /* no structure allocated for this physical card yet */ |
2287 | physcard = kzalloc(sizeof(struct physcard), GFP_KERNEL); | 2294 | physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC); |
2288 | ASSERT(physcard); | 2295 | ASSERT(physcard); |
2289 | 2296 | ||
2290 | physcard->next = slic_global.phys_card; | 2297 | physcard->next = slic_global.phys_card; |
diff --git a/drivers/staging/stlc45xx/Kconfig b/drivers/staging/stlc45xx/Kconfig index 8d3f46f190e8..947fb75a9c68 100644 --- a/drivers/staging/stlc45xx/Kconfig +++ b/drivers/staging/stlc45xx/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config STLC45XX | 1 | config STLC45XX |
2 | tristate "stlc4550/4560 support" | 2 | tristate "stlc4550/4560 support" |
3 | depends on MAC80211 && WLAN_80211 && SPI_MASTER | 3 | depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS |
4 | ---help--- | 4 | ---help--- |
5 | This is a driver for stlc4550 and stlc4560 chipsets. | 5 | This is a driver for stlc4550 and stlc4560 chipsets. |
6 | 6 | ||
diff --git a/drivers/staging/sxg/sxg.c b/drivers/staging/sxg/sxg.c index 891f6e334672..076b3f7d39eb 100644 --- a/drivers/staging/sxg/sxg.c +++ b/drivers/staging/sxg/sxg.c | |||
@@ -322,6 +322,8 @@ int sxg_add_msi_isr(struct adapter_t *adapter) | |||
322 | int ret,i; | 322 | int ret,i; |
323 | 323 | ||
324 | if (!adapter->intrregistered) { | 324 | if (!adapter->intrregistered) { |
325 | spin_unlock_irqrestore(&sxg_global.driver_lock, | ||
326 | sxg_global.flags); | ||
325 | for (i=0; i<adapter->nr_msix_entries; i++) { | 327 | for (i=0; i<adapter->nr_msix_entries; i++) { |
326 | ret = request_irq (adapter->msi_entries[i].vector, | 328 | ret = request_irq (adapter->msi_entries[i].vector, |
327 | sxg_isr, | 329 | sxg_isr, |
@@ -329,6 +331,8 @@ int sxg_add_msi_isr(struct adapter_t *adapter) | |||
329 | adapter->netdev->name, | 331 | adapter->netdev->name, |
330 | adapter->netdev); | 332 | adapter->netdev); |
331 | if (ret) { | 333 | if (ret) { |
334 | spin_lock_irqsave(&sxg_global.driver_lock, | ||
335 | sxg_global.flags); | ||
332 | DBG_ERROR("sxg: MSI-X request_irq (%s) " | 336 | DBG_ERROR("sxg: MSI-X request_irq (%s) " |
333 | "FAILED [%x]\n", adapter->netdev->name, | 337 | "FAILED [%x]\n", adapter->netdev->name, |
334 | ret); | 338 | ret); |
@@ -336,6 +340,7 @@ int sxg_add_msi_isr(struct adapter_t *adapter) | |||
336 | } | 340 | } |
337 | } | 341 | } |
338 | } | 342 | } |
343 | spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags); | ||
339 | adapter->msi_enabled = TRUE; | 344 | adapter->msi_enabled = TRUE; |
340 | adapter->intrregistered = 1; | 345 | adapter->intrregistered = 1; |
341 | adapter->IntRegistered = TRUE; | 346 | adapter->IntRegistered = TRUE; |
@@ -896,6 +901,22 @@ static inline int sxg_read_config(struct adapter_t *adapter) | |||
896 | return status; | 901 | return status; |
897 | } | 902 | } |
898 | 903 | ||
904 | static const struct net_device_ops sxg_netdev_ops = { | ||
905 | .ndo_open = sxg_entry_open, | ||
906 | .ndo_stop = sxg_entry_halt, | ||
907 | .ndo_start_xmit = sxg_send_packets, | ||
908 | .ndo_do_ioctl = sxg_ioctl, | ||
909 | .ndo_change_mtu = sxg_change_mtu, | ||
910 | .ndo_get_stats = sxg_get_stats, | ||
911 | .ndo_set_multicast_list = sxg_mcast_set_list, | ||
912 | .ndo_validate_addr = eth_validate_addr, | ||
913 | #if XXXTODO | ||
914 | .ndo_set_mac_address = sxg_mac_set_address, | ||
915 | #else | ||
916 | .ndo_set_mac_address = eth_mac_addr, | ||
917 | #endif | ||
918 | }; | ||
919 | |||
899 | static int sxg_entry_probe(struct pci_dev *pcidev, | 920 | static int sxg_entry_probe(struct pci_dev *pcidev, |
900 | const struct pci_device_id *pci_tbl_entry) | 921 | const struct pci_device_id *pci_tbl_entry) |
901 | { | 922 | { |
@@ -1095,16 +1116,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev, | |||
1095 | 1116 | ||
1096 | netdev->base_addr = (unsigned long)adapter->base_addr; | 1117 | netdev->base_addr = (unsigned long)adapter->base_addr; |
1097 | netdev->irq = adapter->irq; | 1118 | netdev->irq = adapter->irq; |
1098 | netdev->open = sxg_entry_open; | 1119 | netdev->netdev_ops = &sxg_netdev_ops; |
1099 | netdev->stop = sxg_entry_halt; | ||
1100 | netdev->hard_start_xmit = sxg_send_packets; | ||
1101 | netdev->do_ioctl = sxg_ioctl; | ||
1102 | netdev->change_mtu = sxg_change_mtu; | ||
1103 | #if XXXTODO | ||
1104 | netdev->set_mac_address = sxg_mac_set_address; | ||
1105 | #endif | ||
1106 | netdev->get_stats = sxg_get_stats; | ||
1107 | netdev->set_multicast_list = sxg_mcast_set_list; | ||
1108 | SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops); | 1120 | SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops); |
1109 | netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | 1121 | netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; |
1110 | err = sxg_set_interrupt_capability(adapter); | 1122 | err = sxg_set_interrupt_capability(adapter); |
@@ -2247,6 +2259,8 @@ static int sxg_entry_open(struct net_device *dev) | |||
2247 | DBG_ERROR("sxg: %s EXIT\n", __func__); | 2259 | DBG_ERROR("sxg: %s EXIT\n", __func__); |
2248 | 2260 | ||
2249 | spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); | 2261 | spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags); |
2262 | mod_timer(&adapter->watchdog_timer, jiffies); | ||
2263 | |||
2250 | return STATUS_SUCCESS; | 2264 | return STATUS_SUCCESS; |
2251 | } | 2265 | } |
2252 | 2266 | ||
@@ -2568,6 +2582,7 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2568 | u64 phys_addr; | 2582 | u64 phys_addr; |
2569 | unsigned long flags; | 2583 | unsigned long flags; |
2570 | unsigned long queue_id=0; | 2584 | unsigned long queue_id=0; |
2585 | int offload_cksum = 0; | ||
2571 | 2586 | ||
2572 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl", | 2587 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl", |
2573 | pSgl, SxgSgl, 0, 0); | 2588 | pSgl, SxgSgl, 0, 0); |
@@ -2606,7 +2621,11 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2606 | struct iphdr *ip; | 2621 | struct iphdr *ip; |
2607 | 2622 | ||
2608 | ip = ip_hdr(skb); | 2623 | ip = ip_hdr(skb); |
2609 | if ((ip->protocol == IPPROTO_TCP)&&(DataLength >= sizeof( | 2624 | if (ip->protocol == IPPROTO_TCP) |
2625 | offload_cksum = 1; | ||
2626 | if (!offload_cksum || !tcp_hdr(skb)) | ||
2627 | queue_id = 0; | ||
2628 | else if (offload_cksum && (DataLength >= sizeof( | ||
2610 | struct tcphdr))){ | 2629 | struct tcphdr))){ |
2611 | queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? | 2630 | queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? |
2612 | (ntohs (tcp_hdr(skb)->source) & | 2631 | (ntohs (tcp_hdr(skb)->source) & |
@@ -2615,8 +2634,11 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2615 | SXG_LARGE_SEND_QUEUE_MASK)); | 2634 | SXG_LARGE_SEND_QUEUE_MASK)); |
2616 | } | 2635 | } |
2617 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 2636 | } else if (skb->protocol == htons(ETH_P_IPV6)) { |
2618 | if ((ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (DataLength >= | 2637 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) |
2619 | sizeof(struct tcphdr)) ) { | 2638 | offload_cksum = 1; |
2639 | if (!offload_cksum || !tcp_hdr(skb)) | ||
2640 | queue_id = 0; | ||
2641 | else if (offload_cksum && (DataLength>=sizeof(struct tcphdr))){ | ||
2620 | queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? | 2642 | queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ? |
2621 | (ntohs (tcp_hdr(skb)->source) & | 2643 | (ntohs (tcp_hdr(skb)->source) & |
2622 | SXG_LARGE_SEND_QUEUE_MASK): | 2644 | SXG_LARGE_SEND_QUEUE_MASK): |
@@ -2645,23 +2667,38 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2645 | } | 2667 | } |
2646 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd", | 2668 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd", |
2647 | XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0); | 2669 | XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0); |
2648 | /* Update stats */ | 2670 | memset(XmtCmd, '\0', sizeof(*XmtCmd)); |
2649 | adapter->stats.tx_packets++; | 2671 | XmtCmd->SgEntries = 1; |
2650 | adapter->stats.tx_bytes += DataLength; | 2672 | XmtCmd->Flags = 0; |
2651 | #if XXXTODO /* Stats stuff */ | 2673 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
2652 | if (SXG_MULTICAST_PACKET(EtherHdr)) { | 2674 | /* |
2653 | if (SXG_BROADCAST_PACKET(EtherHdr)) { | 2675 | * We need to set the Checkum in IP header to 0. This is |
2654 | adapter->Stats.DumbXmtBcastPkts++; | 2676 | * required by hardware. |
2655 | adapter->Stats.DumbXmtBcastBytes += DataLength; | 2677 | */ |
2678 | if (offload_cksum) { | ||
2679 | ip_hdr(skb)->check = 0x0; | ||
2680 | XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP; | ||
2681 | XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP; | ||
2682 | /* | ||
2683 | * Dont know if length will require a change in | ||
2684 | * case of VLAN | ||
2685 | */ | ||
2686 | XmtCmd->CsumFlags.MacLen = ETH_HLEN; | ||
2687 | XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >> | ||
2688 | SXG_NW_HDR_LEN_SHIFT; | ||
2656 | } else { | 2689 | } else { |
2657 | adapter->Stats.DumbXmtMcastPkts++; | 2690 | if (skb_checksum_help(skb)){ |
2658 | adapter->Stats.DumbXmtMcastBytes += DataLength; | 2691 | printk(KERN_EMERG "Dropped UDP packet for" |
2692 | " incorrect checksum calculation\n"); | ||
2693 | if (XmtCmd) | ||
2694 | SXG_ABORT_CMD(XmtRingInfo); | ||
2695 | spin_unlock_irqrestore(&adapter->XmtZeroLock, | ||
2696 | flags); | ||
2697 | return STATUS_SUCCESS; | ||
2698 | } | ||
2659 | } | 2699 | } |
2660 | } else { | ||
2661 | adapter->Stats.DumbXmtUcastPkts++; | ||
2662 | adapter->Stats.DumbXmtUcastBytes += DataLength; | ||
2663 | } | 2700 | } |
2664 | #endif | 2701 | |
2665 | /* | 2702 | /* |
2666 | * Fill in the command | 2703 | * Fill in the command |
2667 | * Copy out the first SGE to the command and adjust for offset | 2704 | * Copy out the first SGE to the command and adjust for offset |
@@ -2679,31 +2716,17 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2679 | (SXG_INVALID_SGL(phys_addr,skb->data_len))) | 2716 | (SXG_INVALID_SGL(phys_addr,skb->data_len))) |
2680 | { | 2717 | { |
2681 | spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); | 2718 | spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); |
2719 | if (XmtCmd) | ||
2720 | SXG_ABORT_CMD(XmtRingInfo); | ||
2682 | /* Silently drop this packet */ | 2721 | /* Silently drop this packet */ |
2683 | printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n"); | 2722 | printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n"); |
2684 | return STATUS_SUCCESS; | 2723 | return STATUS_SUCCESS; |
2685 | } | 2724 | } |
2686 | memset(XmtCmd, '\0', sizeof(*XmtCmd)); | ||
2687 | XmtCmd->Buffer.FirstSgeAddress = phys_addr; | 2725 | XmtCmd->Buffer.FirstSgeAddress = phys_addr; |
2688 | XmtCmd->Buffer.FirstSgeLength = DataLength; | 2726 | XmtCmd->Buffer.FirstSgeLength = DataLength; |
2689 | XmtCmd->Buffer.SgeOffset = 0; | 2727 | XmtCmd->Buffer.SgeOffset = 0; |
2690 | XmtCmd->Buffer.TotalLength = DataLength; | 2728 | XmtCmd->Buffer.TotalLength = DataLength; |
2691 | XmtCmd->SgEntries = 1; | ||
2692 | XmtCmd->Flags = 0; | ||
2693 | 2729 | ||
2694 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
2695 | /* | ||
2696 | * We need to set the Checkum in IP header to 0. This is | ||
2697 | * required by hardware. | ||
2698 | */ | ||
2699 | ip_hdr(skb)->check = 0x0; | ||
2700 | XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP; | ||
2701 | XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP; | ||
2702 | /* Dont know if length will require a change in case of VLAN */ | ||
2703 | XmtCmd->CsumFlags.MacLen = ETH_HLEN; | ||
2704 | XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >> | ||
2705 | SXG_NW_HDR_LEN_SHIFT; | ||
2706 | } | ||
2707 | /* | 2730 | /* |
2708 | * Advance transmit cmd descripter by 1. | 2731 | * Advance transmit cmd descripter by 1. |
2709 | * NOTE - See comments in SxgTcpOutput where we write | 2732 | * NOTE - See comments in SxgTcpOutput where we write |
@@ -2715,6 +2738,24 @@ static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl, | |||
2715 | ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0); | 2738 | ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0); |
2716 | WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE); | 2739 | WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE); |
2717 | adapter->Stats.XmtQLen++; /* Stats within lock */ | 2740 | adapter->Stats.XmtQLen++; /* Stats within lock */ |
2741 | /* Update stats */ | ||
2742 | adapter->stats.tx_packets++; | ||
2743 | adapter->stats.tx_bytes += DataLength; | ||
2744 | #if XXXTODO /* Stats stuff */ | ||
2745 | if (SXG_MULTICAST_PACKET(EtherHdr)) { | ||
2746 | if (SXG_BROADCAST_PACKET(EtherHdr)) { | ||
2747 | adapter->Stats.DumbXmtBcastPkts++; | ||
2748 | adapter->Stats.DumbXmtBcastBytes += DataLength; | ||
2749 | } else { | ||
2750 | adapter->Stats.DumbXmtMcastPkts++; | ||
2751 | adapter->Stats.DumbXmtMcastBytes += DataLength; | ||
2752 | } | ||
2753 | } else { | ||
2754 | adapter->Stats.DumbXmtUcastPkts++; | ||
2755 | adapter->Stats.DumbXmtUcastBytes += DataLength; | ||
2756 | } | ||
2757 | #endif | ||
2758 | |||
2718 | spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); | 2759 | spin_unlock_irqrestore(&adapter->XmtZeroLock, flags); |
2719 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2", | 2760 | SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2", |
2720 | XmtCmd, pSgl, SxgSgl, 0); | 2761 | XmtCmd, pSgl, SxgSgl, 0); |
diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c index 85b705453066..9c62f787cc9c 100644 --- a/drivers/staging/uc2322/aten2011.c +++ b/drivers/staging/uc2322/aten2011.c | |||
@@ -603,10 +603,9 @@ static void ATEN2011_bulk_out_data_callback(struct urb *urb) | |||
603 | 603 | ||
604 | tty = tty_port_tty_get(&ATEN2011_port->port->port); | 604 | tty = tty_port_tty_get(&ATEN2011_port->port->port); |
605 | 605 | ||
606 | if (tty && ATEN2011_port->open) { | 606 | if (tty && ATEN2011_port->open) |
607 | /* tell the tty driver that something has changed */ | 607 | /* tell the tty driver that something has changed */ |
608 | wake_up_interruptible(&tty->write_wait); | 608 | tty_wakeup(tty); |
609 | } | ||
610 | 609 | ||
611 | /* schedule_work(&ATEN2011_port->port->work); */ | 610 | /* schedule_work(&ATEN2011_port->port->work); */ |
612 | tty_kref_put(tty); | 611 | tty_kref_put(tty); |
@@ -825,12 +824,6 @@ static int ATEN2011_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
825 | status = 0; | 824 | status = 0; |
826 | status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data); | 825 | status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data); |
827 | 826 | ||
828 | /* force low_latency on so that our tty_push actually forces * | ||
829 | * the data through,otherwise it is scheduled, and with * | ||
830 | * high data rates (like with OHCI) data can get lost. */ | ||
831 | |||
832 | if (tty) | ||
833 | tty->low_latency = 1; | ||
834 | /* | 827 | /* |
835 | * Check to see if we've set up our endpoint info yet | 828 | * Check to see if we've set up our endpoint info yet |
836 | * (can't set it up in ATEN2011_startup as the structures | 829 | * (can't set it up in ATEN2011_startup as the structures |
@@ -1473,22 +1466,7 @@ static void ATEN2011_set_termios(struct tty_struct *tty, | |||
1473 | 1466 | ||
1474 | cflag = tty->termios->c_cflag; | 1467 | cflag = tty->termios->c_cflag; |
1475 | 1468 | ||
1476 | if (!cflag) { | 1469 | dbg("%s - cflag %08x iflag %08x", __func__, |
1477 | dbg("%s %s", __func__, "cflag is NULL"); | ||
1478 | return; | ||
1479 | } | ||
1480 | |||
1481 | /* check that they really want us to change something */ | ||
1482 | if (old_termios) { | ||
1483 | if ((cflag == old_termios->c_cflag) && | ||
1484 | (RELEVANT_IFLAG(tty->termios->c_iflag) == | ||
1485 | RELEVANT_IFLAG(old_termios->c_iflag))) { | ||
1486 | dbg("%s", "Nothing to change"); | ||
1487 | return; | ||
1488 | } | ||
1489 | } | ||
1490 | |||
1491 | dbg("%s - clfag %08x iflag %08x", __func__, | ||
1492 | tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); | 1470 | tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); |
1493 | 1471 | ||
1494 | if (old_termios) { | 1472 | if (old_termios) { |
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index b2a606a36936..393e4df70dfd 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c | |||
@@ -711,6 +711,20 @@ static int wlan_change_mtu(netdevice_t *dev, int new_mtu) | |||
711 | return 0; | 711 | return 0; |
712 | } | 712 | } |
713 | 713 | ||
714 | static const struct net_device_ops p80211_netdev_ops = { | ||
715 | .ndo_init = p80211knetdev_init, | ||
716 | .ndo_open = p80211knetdev_open, | ||
717 | .ndo_stop = p80211knetdev_stop, | ||
718 | .ndo_get_stats = p80211knetdev_get_stats, | ||
719 | .ndo_start_xmit = p80211knetdev_hard_start_xmit, | ||
720 | .ndo_set_multicast_list = p80211knetdev_set_multicast_list, | ||
721 | .ndo_do_ioctl = p80211knetdev_do_ioctl, | ||
722 | .ndo_set_mac_address = p80211knetdev_set_mac_address, | ||
723 | .ndo_tx_timeout = p80211knetdev_tx_timeout, | ||
724 | .ndo_change_mtu = wlan_change_mtu, | ||
725 | .ndo_validate_addr = eth_validate_addr, | ||
726 | }; | ||
727 | |||
714 | /*---------------------------------------------------------------- | 728 | /*---------------------------------------------------------------- |
715 | * wlan_setup | 729 | * wlan_setup |
716 | * | 730 | * |
@@ -756,11 +770,7 @@ int wlan_setup(wlandevice_t *wlandev) | |||
756 | } else { | 770 | } else { |
757 | wlandev->netdev = dev; | 771 | wlandev->netdev = dev; |
758 | dev->ml_priv = wlandev; | 772 | dev->ml_priv = wlandev; |
759 | dev->hard_start_xmit = p80211knetdev_hard_start_xmit; | 773 | dev->netdev_ops = &p80211_netdev_ops; |
760 | dev->get_stats = p80211knetdev_get_stats; | ||
761 | dev->init = p80211knetdev_init; | ||
762 | dev->open = p80211knetdev_open; | ||
763 | dev->stop = p80211knetdev_stop; | ||
764 | 774 | ||
765 | mutex_init(&wlandev->ioctl_lock); | 775 | mutex_init(&wlandev->ioctl_lock); |
766 | /* block ioctls until fully initialised. Don't forget to call | 776 | /* block ioctls until fully initialised. Don't forget to call |