diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/hvcs.c | 2 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_devintf.c | 18 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_kcs_sm.c | 8 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 80 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_poweroff.c | 2 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 85 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_watchdog.c | 61 | ||||
-rw-r--r-- | drivers/char/istallion.c | 32 | ||||
-rw-r--r-- | drivers/char/keyboard.c | 118 | ||||
-rw-r--r-- | drivers/char/pcmcia/cm4000_cs.c | 121 | ||||
-rw-r--r-- | drivers/char/pcmcia/cm4040_cs.c | 133 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 116 | ||||
-rw-r--r-- | drivers/char/stallion.c | 46 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 2 | ||||
-rw-r--r-- | drivers/char/vt.c | 4 | ||||
-rw-r--r-- | drivers/char/watchdog/Kconfig | 7 | ||||
-rw-r--r-- | drivers/char/watchdog/Makefile | 1 | ||||
-rw-r--r-- | drivers/char/watchdog/at91_wdt.c | 228 | ||||
-rw-r--r-- | drivers/char/watchdog/pcwd.c | 137 | ||||
-rw-r--r-- | drivers/char/watchdog/pcwd_usb.c | 3 |
20 files changed, 741 insertions, 463 deletions
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 327b00c3c45e..8d97b3911293 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -904,7 +904,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address, | |||
904 | * It is possible the vty-server was removed after the irq was | 904 | * It is possible the vty-server was removed after the irq was |
905 | * requested but before we have time to enable interrupts. | 905 | * requested but before we have time to enable interrupts. |
906 | */ | 906 | */ |
907 | if (vio_enable_interrupts(vdev) == H_Success) | 907 | if (vio_enable_interrupts(vdev) == H_SUCCESS) |
908 | return 0; | 908 | return 0; |
909 | else { | 909 | else { |
910 | printk(KERN_ERR "HVCS: int enable failed for" | 910 | printk(KERN_ERR "HVCS: int enable failed for" |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 932feedda262..e1c95374984c 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/devfs_fs_kernel.h> | 43 | #include <linux/devfs_fs_kernel.h> |
44 | #include <linux/ipmi.h> | 44 | #include <linux/ipmi.h> |
45 | #include <asm/semaphore.h> | 45 | #include <linux/mutex.h> |
46 | #include <linux/init.h> | 46 | #include <linux/init.h> |
47 | #include <linux/device.h> | 47 | #include <linux/device.h> |
48 | #include <linux/compat.h> | 48 | #include <linux/compat.h> |
@@ -55,7 +55,7 @@ struct ipmi_file_private | |||
55 | struct file *file; | 55 | struct file *file; |
56 | struct fasync_struct *fasync_queue; | 56 | struct fasync_struct *fasync_queue; |
57 | wait_queue_head_t wait; | 57 | wait_queue_head_t wait; |
58 | struct semaphore recv_sem; | 58 | struct mutex recv_mutex; |
59 | int default_retries; | 59 | int default_retries; |
60 | unsigned int default_retry_time_ms; | 60 | unsigned int default_retry_time_ms; |
61 | }; | 61 | }; |
@@ -141,7 +141,7 @@ static int ipmi_open(struct inode *inode, struct file *file) | |||
141 | INIT_LIST_HEAD(&(priv->recv_msgs)); | 141 | INIT_LIST_HEAD(&(priv->recv_msgs)); |
142 | init_waitqueue_head(&priv->wait); | 142 | init_waitqueue_head(&priv->wait); |
143 | priv->fasync_queue = NULL; | 143 | priv->fasync_queue = NULL; |
144 | sema_init(&(priv->recv_sem), 1); | 144 | mutex_init(&priv->recv_mutex); |
145 | 145 | ||
146 | /* Use the low-level defaults. */ | 146 | /* Use the low-level defaults. */ |
147 | priv->default_retries = -1; | 147 | priv->default_retries = -1; |
@@ -285,15 +285,15 @@ static int ipmi_ioctl(struct inode *inode, | |||
285 | break; | 285 | break; |
286 | } | 286 | } |
287 | 287 | ||
288 | /* We claim a semaphore because we don't want two | 288 | /* We claim a mutex because we don't want two |
289 | users getting something from the queue at a time. | 289 | users getting something from the queue at a time. |
290 | Since we have to release the spinlock before we can | 290 | Since we have to release the spinlock before we can |
291 | copy the data to the user, it's possible another | 291 | copy the data to the user, it's possible another |
292 | user will grab something from the queue, too. Then | 292 | user will grab something from the queue, too. Then |
293 | the messages might get out of order if something | 293 | the messages might get out of order if something |
294 | fails and the message gets put back onto the | 294 | fails and the message gets put back onto the |
295 | queue. This semaphore prevents that problem. */ | 295 | queue. This mutex prevents that problem. */ |
296 | down(&(priv->recv_sem)); | 296 | mutex_lock(&priv->recv_mutex); |
297 | 297 | ||
298 | /* Grab the message off the list. */ | 298 | /* Grab the message off the list. */ |
299 | spin_lock_irqsave(&(priv->recv_msg_lock), flags); | 299 | spin_lock_irqsave(&(priv->recv_msg_lock), flags); |
@@ -352,7 +352,7 @@ static int ipmi_ioctl(struct inode *inode, | |||
352 | goto recv_putback_on_err; | 352 | goto recv_putback_on_err; |
353 | } | 353 | } |
354 | 354 | ||
355 | up(&(priv->recv_sem)); | 355 | mutex_unlock(&priv->recv_mutex); |
356 | ipmi_free_recv_msg(msg); | 356 | ipmi_free_recv_msg(msg); |
357 | break; | 357 | break; |
358 | 358 | ||
@@ -362,11 +362,11 @@ static int ipmi_ioctl(struct inode *inode, | |||
362 | spin_lock_irqsave(&(priv->recv_msg_lock), flags); | 362 | spin_lock_irqsave(&(priv->recv_msg_lock), flags); |
363 | list_add(entry, &(priv->recv_msgs)); | 363 | list_add(entry, &(priv->recv_msgs)); |
364 | spin_unlock_irqrestore(&(priv->recv_msg_lock), flags); | 364 | spin_unlock_irqrestore(&(priv->recv_msg_lock), flags); |
365 | up(&(priv->recv_sem)); | 365 | mutex_unlock(&priv->recv_mutex); |
366 | break; | 366 | break; |
367 | 367 | ||
368 | recv_err: | 368 | recv_err: |
369 | up(&(priv->recv_sem)); | 369 | mutex_unlock(&priv->recv_mutex); |
370 | break; | 370 | break; |
371 | } | 371 | } |
372 | 372 | ||
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c index da1554194d3d..2062675f9e99 100644 --- a/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/drivers/char/ipmi/ipmi_kcs_sm.c | |||
@@ -227,7 +227,7 @@ static inline int check_ibf(struct si_sm_data *kcs, unsigned char status, | |||
227 | static inline int check_obf(struct si_sm_data *kcs, unsigned char status, | 227 | static inline int check_obf(struct si_sm_data *kcs, unsigned char status, |
228 | long time) | 228 | long time) |
229 | { | 229 | { |
230 | if (! GET_STATUS_OBF(status)) { | 230 | if (!GET_STATUS_OBF(status)) { |
231 | kcs->obf_timeout -= time; | 231 | kcs->obf_timeout -= time; |
232 | if (kcs->obf_timeout < 0) { | 232 | if (kcs->obf_timeout < 0) { |
233 | start_error_recovery(kcs, "OBF not ready in time"); | 233 | start_error_recovery(kcs, "OBF not ready in time"); |
@@ -407,7 +407,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
407 | } | 407 | } |
408 | 408 | ||
409 | if (state == KCS_READ_STATE) { | 409 | if (state == KCS_READ_STATE) { |
410 | if (! check_obf(kcs, status, time)) | 410 | if (!check_obf(kcs, status, time)) |
411 | return SI_SM_CALL_WITH_DELAY; | 411 | return SI_SM_CALL_WITH_DELAY; |
412 | read_next_byte(kcs); | 412 | read_next_byte(kcs); |
413 | } else { | 413 | } else { |
@@ -447,7 +447,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
447 | "Not in read state for error2"); | 447 | "Not in read state for error2"); |
448 | break; | 448 | break; |
449 | } | 449 | } |
450 | if (! check_obf(kcs, status, time)) | 450 | if (!check_obf(kcs, status, time)) |
451 | return SI_SM_CALL_WITH_DELAY; | 451 | return SI_SM_CALL_WITH_DELAY; |
452 | 452 | ||
453 | clear_obf(kcs, status); | 453 | clear_obf(kcs, status); |
@@ -462,7 +462,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
462 | break; | 462 | break; |
463 | } | 463 | } |
464 | 464 | ||
465 | if (! check_obf(kcs, status, time)) | 465 | if (!check_obf(kcs, status, time)) |
466 | return SI_SM_CALL_WITH_DELAY; | 466 | return SI_SM_CALL_WITH_DELAY; |
467 | 467 | ||
468 | clear_obf(kcs, status); | 468 | clear_obf(kcs, status); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 40eb005b9d77..0ded046d5aa8 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <linux/poll.h> | 39 | #include <linux/poll.h> |
40 | #include <linux/spinlock.h> | 40 | #include <linux/spinlock.h> |
41 | #include <linux/mutex.h> | ||
41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
42 | #include <linux/ipmi.h> | 43 | #include <linux/ipmi.h> |
43 | #include <linux/ipmi_smi.h> | 44 | #include <linux/ipmi_smi.h> |
@@ -234,7 +235,7 @@ struct ipmi_smi | |||
234 | 235 | ||
235 | /* The list of command receivers that are registered for commands | 236 | /* The list of command receivers that are registered for commands |
236 | on this interface. */ | 237 | on this interface. */ |
237 | struct semaphore cmd_rcvrs_lock; | 238 | struct mutex cmd_rcvrs_mutex; |
238 | struct list_head cmd_rcvrs; | 239 | struct list_head cmd_rcvrs; |
239 | 240 | ||
240 | /* Events that were queues because no one was there to receive | 241 | /* Events that were queues because no one was there to receive |
@@ -387,10 +388,10 @@ static void clean_up_interface_data(ipmi_smi_t intf) | |||
387 | 388 | ||
388 | /* Wholesale remove all the entries from the list in the | 389 | /* Wholesale remove all the entries from the list in the |
389 | * interface and wait for RCU to know that none are in use. */ | 390 | * interface and wait for RCU to know that none are in use. */ |
390 | down(&intf->cmd_rcvrs_lock); | 391 | mutex_lock(&intf->cmd_rcvrs_mutex); |
391 | list_add_rcu(&list, &intf->cmd_rcvrs); | 392 | list_add_rcu(&list, &intf->cmd_rcvrs); |
392 | list_del_rcu(&intf->cmd_rcvrs); | 393 | list_del_rcu(&intf->cmd_rcvrs); |
393 | up(&intf->cmd_rcvrs_lock); | 394 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
394 | synchronize_rcu(); | 395 | synchronize_rcu(); |
395 | 396 | ||
396 | list_for_each_entry_safe(rcvr, rcvr2, &list, link) | 397 | list_for_each_entry_safe(rcvr, rcvr2, &list, link) |
@@ -557,7 +558,7 @@ unsigned int ipmi_addr_length(int addr_type) | |||
557 | 558 | ||
558 | static void deliver_response(struct ipmi_recv_msg *msg) | 559 | static void deliver_response(struct ipmi_recv_msg *msg) |
559 | { | 560 | { |
560 | if (! msg->user) { | 561 | if (!msg->user) { |
561 | ipmi_smi_t intf = msg->user_msg_data; | 562 | ipmi_smi_t intf = msg->user_msg_data; |
562 | unsigned long flags; | 563 | unsigned long flags; |
563 | 564 | ||
@@ -598,11 +599,11 @@ static int intf_next_seq(ipmi_smi_t intf, | |||
598 | (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; | 599 | (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; |
599 | i = (i+1)%IPMI_IPMB_NUM_SEQ) | 600 | i = (i+1)%IPMI_IPMB_NUM_SEQ) |
600 | { | 601 | { |
601 | if (! intf->seq_table[i].inuse) | 602 | if (!intf->seq_table[i].inuse) |
602 | break; | 603 | break; |
603 | } | 604 | } |
604 | 605 | ||
605 | if (! intf->seq_table[i].inuse) { | 606 | if (!intf->seq_table[i].inuse) { |
606 | intf->seq_table[i].recv_msg = recv_msg; | 607 | intf->seq_table[i].recv_msg = recv_msg; |
607 | 608 | ||
608 | /* Start with the maximum timeout, when the send response | 609 | /* Start with the maximum timeout, when the send response |
@@ -763,7 +764,7 @@ int ipmi_create_user(unsigned int if_num, | |||
763 | } | 764 | } |
764 | 765 | ||
765 | new_user = kmalloc(sizeof(*new_user), GFP_KERNEL); | 766 | new_user = kmalloc(sizeof(*new_user), GFP_KERNEL); |
766 | if (! new_user) | 767 | if (!new_user) |
767 | return -ENOMEM; | 768 | return -ENOMEM; |
768 | 769 | ||
769 | spin_lock_irqsave(&interfaces_lock, flags); | 770 | spin_lock_irqsave(&interfaces_lock, flags); |
@@ -819,14 +820,13 @@ static void free_user(struct kref *ref) | |||
819 | 820 | ||
820 | int ipmi_destroy_user(ipmi_user_t user) | 821 | int ipmi_destroy_user(ipmi_user_t user) |
821 | { | 822 | { |
822 | int rv = -ENODEV; | ||
823 | ipmi_smi_t intf = user->intf; | 823 | ipmi_smi_t intf = user->intf; |
824 | int i; | 824 | int i; |
825 | unsigned long flags; | 825 | unsigned long flags; |
826 | struct cmd_rcvr *rcvr; | 826 | struct cmd_rcvr *rcvr; |
827 | struct cmd_rcvr *rcvrs = NULL; | 827 | struct cmd_rcvr *rcvrs = NULL; |
828 | 828 | ||
829 | user->valid = 1; | 829 | user->valid = 0; |
830 | 830 | ||
831 | /* Remove the user from the interface's sequence table. */ | 831 | /* Remove the user from the interface's sequence table. */ |
832 | spin_lock_irqsave(&intf->seq_lock, flags); | 832 | spin_lock_irqsave(&intf->seq_lock, flags); |
@@ -847,7 +847,7 @@ int ipmi_destroy_user(ipmi_user_t user) | |||
847 | * since other things may be using it till we do | 847 | * since other things may be using it till we do |
848 | * synchronize_rcu()) then free everything in that list. | 848 | * synchronize_rcu()) then free everything in that list. |
849 | */ | 849 | */ |
850 | down(&intf->cmd_rcvrs_lock); | 850 | mutex_lock(&intf->cmd_rcvrs_mutex); |
851 | list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) { | 851 | list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) { |
852 | if (rcvr->user == user) { | 852 | if (rcvr->user == user) { |
853 | list_del_rcu(&rcvr->link); | 853 | list_del_rcu(&rcvr->link); |
@@ -855,7 +855,7 @@ int ipmi_destroy_user(ipmi_user_t user) | |||
855 | rcvrs = rcvr; | 855 | rcvrs = rcvr; |
856 | } | 856 | } |
857 | } | 857 | } |
858 | up(&intf->cmd_rcvrs_lock); | 858 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
859 | synchronize_rcu(); | 859 | synchronize_rcu(); |
860 | while (rcvrs) { | 860 | while (rcvrs) { |
861 | rcvr = rcvrs; | 861 | rcvr = rcvrs; |
@@ -871,7 +871,7 @@ int ipmi_destroy_user(ipmi_user_t user) | |||
871 | 871 | ||
872 | kref_put(&user->refcount, free_user); | 872 | kref_put(&user->refcount, free_user); |
873 | 873 | ||
874 | return rv; | 874 | return 0; |
875 | } | 875 | } |
876 | 876 | ||
877 | void ipmi_get_version(ipmi_user_t user, | 877 | void ipmi_get_version(ipmi_user_t user, |
@@ -936,7 +936,8 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) | |||
936 | 936 | ||
937 | if (val) { | 937 | if (val) { |
938 | /* Deliver any queued events. */ | 938 | /* Deliver any queued events. */ |
939 | list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) { | 939 | list_for_each_entry_safe(msg, msg2, &intf->waiting_events, |
940 | link) { | ||
940 | list_del(&msg->link); | 941 | list_del(&msg->link); |
941 | list_add_tail(&msg->link, &msgs); | 942 | list_add_tail(&msg->link, &msgs); |
942 | } | 943 | } |
@@ -978,13 +979,13 @@ int ipmi_register_for_cmd(ipmi_user_t user, | |||
978 | 979 | ||
979 | 980 | ||
980 | rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); | 981 | rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); |
981 | if (! rcvr) | 982 | if (!rcvr) |
982 | return -ENOMEM; | 983 | return -ENOMEM; |
983 | rcvr->cmd = cmd; | 984 | rcvr->cmd = cmd; |
984 | rcvr->netfn = netfn; | 985 | rcvr->netfn = netfn; |
985 | rcvr->user = user; | 986 | rcvr->user = user; |
986 | 987 | ||
987 | down(&intf->cmd_rcvrs_lock); | 988 | mutex_lock(&intf->cmd_rcvrs_mutex); |
988 | /* Make sure the command/netfn is not already registered. */ | 989 | /* Make sure the command/netfn is not already registered. */ |
989 | entry = find_cmd_rcvr(intf, netfn, cmd); | 990 | entry = find_cmd_rcvr(intf, netfn, cmd); |
990 | if (entry) { | 991 | if (entry) { |
@@ -995,7 +996,7 @@ int ipmi_register_for_cmd(ipmi_user_t user, | |||
995 | list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); | 996 | list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); |
996 | 997 | ||
997 | out_unlock: | 998 | out_unlock: |
998 | up(&intf->cmd_rcvrs_lock); | 999 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
999 | if (rv) | 1000 | if (rv) |
1000 | kfree(rcvr); | 1001 | kfree(rcvr); |
1001 | 1002 | ||
@@ -1009,17 +1010,17 @@ int ipmi_unregister_for_cmd(ipmi_user_t user, | |||
1009 | ipmi_smi_t intf = user->intf; | 1010 | ipmi_smi_t intf = user->intf; |
1010 | struct cmd_rcvr *rcvr; | 1011 | struct cmd_rcvr *rcvr; |
1011 | 1012 | ||
1012 | down(&intf->cmd_rcvrs_lock); | 1013 | mutex_lock(&intf->cmd_rcvrs_mutex); |
1013 | /* Make sure the command/netfn is not already registered. */ | 1014 | /* Make sure the command/netfn is not already registered. */ |
1014 | rcvr = find_cmd_rcvr(intf, netfn, cmd); | 1015 | rcvr = find_cmd_rcvr(intf, netfn, cmd); |
1015 | if ((rcvr) && (rcvr->user == user)) { | 1016 | if ((rcvr) && (rcvr->user == user)) { |
1016 | list_del_rcu(&rcvr->link); | 1017 | list_del_rcu(&rcvr->link); |
1017 | up(&intf->cmd_rcvrs_lock); | 1018 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
1018 | synchronize_rcu(); | 1019 | synchronize_rcu(); |
1019 | kfree(rcvr); | 1020 | kfree(rcvr); |
1020 | return 0; | 1021 | return 0; |
1021 | } else { | 1022 | } else { |
1022 | up(&intf->cmd_rcvrs_lock); | 1023 | mutex_unlock(&intf->cmd_rcvrs_mutex); |
1023 | return -ENOENT; | 1024 | return -ENOENT; |
1024 | } | 1025 | } |
1025 | } | 1026 | } |
@@ -1514,7 +1515,7 @@ int ipmi_request_settime(ipmi_user_t user, | |||
1514 | unsigned char saddr, lun; | 1515 | unsigned char saddr, lun; |
1515 | int rv; | 1516 | int rv; |
1516 | 1517 | ||
1517 | if (! user) | 1518 | if (!user) |
1518 | return -EINVAL; | 1519 | return -EINVAL; |
1519 | rv = check_addr(user->intf, addr, &saddr, &lun); | 1520 | rv = check_addr(user->intf, addr, &saddr, &lun); |
1520 | if (rv) | 1521 | if (rv) |
@@ -1545,7 +1546,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user, | |||
1545 | unsigned char saddr, lun; | 1546 | unsigned char saddr, lun; |
1546 | int rv; | 1547 | int rv; |
1547 | 1548 | ||
1548 | if (! user) | 1549 | if (!user) |
1549 | return -EINVAL; | 1550 | return -EINVAL; |
1550 | rv = check_addr(user->intf, addr, &saddr, &lun); | 1551 | rv = check_addr(user->intf, addr, &saddr, &lun); |
1551 | if (rv) | 1552 | if (rv) |
@@ -1570,7 +1571,7 @@ static int ipmb_file_read_proc(char *page, char **start, off_t off, | |||
1570 | char *out = (char *) page; | 1571 | char *out = (char *) page; |
1571 | ipmi_smi_t intf = data; | 1572 | ipmi_smi_t intf = data; |
1572 | int i; | 1573 | int i; |
1573 | int rv= 0; | 1574 | int rv = 0; |
1574 | 1575 | ||
1575 | for (i = 0; i < IPMI_MAX_CHANNELS; i++) | 1576 | for (i = 0; i < IPMI_MAX_CHANNELS; i++) |
1576 | rv += sprintf(out+rv, "%x ", intf->channels[i].address); | 1577 | rv += sprintf(out+rv, "%x ", intf->channels[i].address); |
@@ -1989,7 +1990,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
1989 | } else { | 1990 | } else { |
1990 | bmc->dev = platform_device_alloc("ipmi_bmc", | 1991 | bmc->dev = platform_device_alloc("ipmi_bmc", |
1991 | bmc->id.device_id); | 1992 | bmc->id.device_id); |
1992 | if (! bmc->dev) { | 1993 | if (!bmc->dev) { |
1993 | printk(KERN_ERR | 1994 | printk(KERN_ERR |
1994 | "ipmi_msghandler:" | 1995 | "ipmi_msghandler:" |
1995 | " Unable to allocate platform device\n"); | 1996 | " Unable to allocate platform device\n"); |
@@ -2305,8 +2306,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2305 | void *send_info, | 2306 | void *send_info, |
2306 | struct ipmi_device_id *device_id, | 2307 | struct ipmi_device_id *device_id, |
2307 | struct device *si_dev, | 2308 | struct device *si_dev, |
2308 | unsigned char slave_addr, | 2309 | unsigned char slave_addr) |
2309 | ipmi_smi_t *new_intf) | ||
2310 | { | 2310 | { |
2311 | int i, j; | 2311 | int i, j; |
2312 | int rv; | 2312 | int rv; |
@@ -2366,7 +2366,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2366 | spin_lock_init(&intf->events_lock); | 2366 | spin_lock_init(&intf->events_lock); |
2367 | INIT_LIST_HEAD(&intf->waiting_events); | 2367 | INIT_LIST_HEAD(&intf->waiting_events); |
2368 | intf->waiting_events_count = 0; | 2368 | intf->waiting_events_count = 0; |
2369 | init_MUTEX(&intf->cmd_rcvrs_lock); | 2369 | mutex_init(&intf->cmd_rcvrs_mutex); |
2370 | INIT_LIST_HEAD(&intf->cmd_rcvrs); | 2370 | INIT_LIST_HEAD(&intf->cmd_rcvrs); |
2371 | init_waitqueue_head(&intf->waitq); | 2371 | init_waitqueue_head(&intf->waitq); |
2372 | 2372 | ||
@@ -2388,9 +2388,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2388 | if (rv) | 2388 | if (rv) |
2389 | goto out; | 2389 | goto out; |
2390 | 2390 | ||
2391 | /* FIXME - this is an ugly kludge, this sets the intf for the | 2391 | rv = handlers->start_processing(send_info, intf); |
2392 | caller before sending any messages with it. */ | 2392 | if (rv) |
2393 | *new_intf = intf; | 2393 | goto out; |
2394 | 2394 | ||
2395 | get_guid(intf); | 2395 | get_guid(intf); |
2396 | 2396 | ||
@@ -2622,7 +2622,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, | |||
2622 | spin_unlock_irqrestore(&intf->counter_lock, flags); | 2622 | spin_unlock_irqrestore(&intf->counter_lock, flags); |
2623 | 2623 | ||
2624 | recv_msg = ipmi_alloc_recv_msg(); | 2624 | recv_msg = ipmi_alloc_recv_msg(); |
2625 | if (! recv_msg) { | 2625 | if (!recv_msg) { |
2626 | /* We couldn't allocate memory for the | 2626 | /* We couldn't allocate memory for the |
2627 | message, so requeue it for handling | 2627 | message, so requeue it for handling |
2628 | later. */ | 2628 | later. */ |
@@ -2777,7 +2777,7 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf, | |||
2777 | spin_unlock_irqrestore(&intf->counter_lock, flags); | 2777 | spin_unlock_irqrestore(&intf->counter_lock, flags); |
2778 | 2778 | ||
2779 | recv_msg = ipmi_alloc_recv_msg(); | 2779 | recv_msg = ipmi_alloc_recv_msg(); |
2780 | if (! recv_msg) { | 2780 | if (!recv_msg) { |
2781 | /* We couldn't allocate memory for the | 2781 | /* We couldn't allocate memory for the |
2782 | message, so requeue it for handling | 2782 | message, so requeue it for handling |
2783 | later. */ | 2783 | later. */ |
@@ -2869,13 +2869,14 @@ static int handle_read_event_rsp(ipmi_smi_t intf, | |||
2869 | events. */ | 2869 | events. */ |
2870 | rcu_read_lock(); | 2870 | rcu_read_lock(); |
2871 | list_for_each_entry_rcu(user, &intf->users, link) { | 2871 | list_for_each_entry_rcu(user, &intf->users, link) { |
2872 | if (! user->gets_events) | 2872 | if (!user->gets_events) |
2873 | continue; | 2873 | continue; |
2874 | 2874 | ||
2875 | recv_msg = ipmi_alloc_recv_msg(); | 2875 | recv_msg = ipmi_alloc_recv_msg(); |
2876 | if (! recv_msg) { | 2876 | if (!recv_msg) { |
2877 | rcu_read_unlock(); | 2877 | rcu_read_unlock(); |
2878 | list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) { | 2878 | list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, |
2879 | link) { | ||
2879 | list_del(&recv_msg->link); | 2880 | list_del(&recv_msg->link); |
2880 | ipmi_free_recv_msg(recv_msg); | 2881 | ipmi_free_recv_msg(recv_msg); |
2881 | } | 2882 | } |
@@ -2905,7 +2906,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf, | |||
2905 | /* No one to receive the message, put it in queue if there's | 2906 | /* No one to receive the message, put it in queue if there's |
2906 | not already too many things in the queue. */ | 2907 | not already too many things in the queue. */ |
2907 | recv_msg = ipmi_alloc_recv_msg(); | 2908 | recv_msg = ipmi_alloc_recv_msg(); |
2908 | if (! recv_msg) { | 2909 | if (!recv_msg) { |
2909 | /* We couldn't allocate memory for the | 2910 | /* We couldn't allocate memory for the |
2910 | message, so requeue it for handling | 2911 | message, so requeue it for handling |
2911 | later. */ | 2912 | later. */ |
@@ -3190,7 +3191,7 @@ void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf) | |||
3190 | 3191 | ||
3191 | rcu_read_lock(); | 3192 | rcu_read_lock(); |
3192 | list_for_each_entry_rcu(user, &intf->users, link) { | 3193 | list_for_each_entry_rcu(user, &intf->users, link) { |
3193 | if (! user->handler->ipmi_watchdog_pretimeout) | 3194 | if (!user->handler->ipmi_watchdog_pretimeout) |
3194 | continue; | 3195 | continue; |
3195 | 3196 | ||
3196 | user->handler->ipmi_watchdog_pretimeout(user->handler_data); | 3197 | user->handler->ipmi_watchdog_pretimeout(user->handler_data); |
@@ -3278,7 +3279,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
3278 | 3279 | ||
3279 | smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, | 3280 | smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, |
3280 | ent->seqid); | 3281 | ent->seqid); |
3281 | if (! smi_msg) | 3282 | if (!smi_msg) |
3282 | return; | 3283 | return; |
3283 | 3284 | ||
3284 | spin_unlock_irqrestore(&intf->seq_lock, *flags); | 3285 | spin_unlock_irqrestore(&intf->seq_lock, *flags); |
@@ -3314,8 +3315,9 @@ static void ipmi_timeout_handler(long timeout_period) | |||
3314 | 3315 | ||
3315 | /* See if any waiting messages need to be processed. */ | 3316 | /* See if any waiting messages need to be processed. */ |
3316 | spin_lock_irqsave(&intf->waiting_msgs_lock, flags); | 3317 | spin_lock_irqsave(&intf->waiting_msgs_lock, flags); |
3317 | list_for_each_entry_safe(smi_msg, smi_msg2, &intf->waiting_msgs, link) { | 3318 | list_for_each_entry_safe(smi_msg, smi_msg2, |
3318 | if (! handle_new_recv_msg(intf, smi_msg)) { | 3319 | &intf->waiting_msgs, link) { |
3320 | if (!handle_new_recv_msg(intf, smi_msg)) { | ||
3319 | list_del(&smi_msg->link); | 3321 | list_del(&smi_msg->link); |
3320 | ipmi_free_smi_msg(smi_msg); | 3322 | ipmi_free_smi_msg(smi_msg); |
3321 | } else { | 3323 | } else { |
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index 786a2802ca34..d0b5c08e7b4e 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
@@ -346,7 +346,7 @@ static int ipmi_dell_chassis_detect (ipmi_user_t user) | |||
346 | { | 346 | { |
347 | const char ipmi_version_major = ipmi_version & 0xF; | 347 | const char ipmi_version_major = ipmi_version & 0xF; |
348 | const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; | 348 | const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; |
349 | const char mfr[3]=DELL_IANA_MFR_ID; | 349 | const char mfr[3] = DELL_IANA_MFR_ID; |
350 | if (!memcmp(mfr, &mfg_id, sizeof(mfr)) && | 350 | if (!memcmp(mfr, &mfg_id, sizeof(mfr)) && |
351 | ipmi_version_major <= 1 && | 351 | ipmi_version_major <= 1 && |
352 | ipmi_version_minor < 5) | 352 | ipmi_version_minor < 5) |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 35fbd4d8ed4b..a86c0f29953e 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -803,7 +803,7 @@ static int ipmi_thread(void *data) | |||
803 | set_user_nice(current, 19); | 803 | set_user_nice(current, 19); |
804 | while (!kthread_should_stop()) { | 804 | while (!kthread_should_stop()) { |
805 | spin_lock_irqsave(&(smi_info->si_lock), flags); | 805 | spin_lock_irqsave(&(smi_info->si_lock), flags); |
806 | smi_result=smi_event_handler(smi_info, 0); | 806 | smi_result = smi_event_handler(smi_info, 0); |
807 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | 807 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); |
808 | if (smi_result == SI_SM_CALL_WITHOUT_DELAY) { | 808 | if (smi_result == SI_SM_CALL_WITHOUT_DELAY) { |
809 | /* do nothing */ | 809 | /* do nothing */ |
@@ -972,10 +972,37 @@ static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs) | |||
972 | return si_irq_handler(irq, data, regs); | 972 | return si_irq_handler(irq, data, regs); |
973 | } | 973 | } |
974 | 974 | ||
975 | static int smi_start_processing(void *send_info, | ||
976 | ipmi_smi_t intf) | ||
977 | { | ||
978 | struct smi_info *new_smi = send_info; | ||
979 | |||
980 | new_smi->intf = intf; | ||
981 | |||
982 | /* Set up the timer that drives the interface. */ | ||
983 | setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); | ||
984 | new_smi->last_timeout_jiffies = jiffies; | ||
985 | mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES); | ||
986 | |||
987 | if (new_smi->si_type != SI_BT) { | ||
988 | new_smi->thread = kthread_run(ipmi_thread, new_smi, | ||
989 | "kipmi%d", new_smi->intf_num); | ||
990 | if (IS_ERR(new_smi->thread)) { | ||
991 | printk(KERN_NOTICE "ipmi_si_intf: Could not start" | ||
992 | " kernel thread due to error %ld, only using" | ||
993 | " timers to drive the interface\n", | ||
994 | PTR_ERR(new_smi->thread)); | ||
995 | new_smi->thread = NULL; | ||
996 | } | ||
997 | } | ||
998 | |||
999 | return 0; | ||
1000 | } | ||
975 | 1001 | ||
976 | static struct ipmi_smi_handlers handlers = | 1002 | static struct ipmi_smi_handlers handlers = |
977 | { | 1003 | { |
978 | .owner = THIS_MODULE, | 1004 | .owner = THIS_MODULE, |
1005 | .start_processing = smi_start_processing, | ||
979 | .sender = sender, | 1006 | .sender = sender, |
980 | .request_events = request_events, | 1007 | .request_events = request_events, |
981 | .set_run_to_completion = set_run_to_completion, | 1008 | .set_run_to_completion = set_run_to_completion, |
@@ -987,7 +1014,7 @@ static struct ipmi_smi_handlers handlers = | |||
987 | 1014 | ||
988 | #define SI_MAX_PARMS 4 | 1015 | #define SI_MAX_PARMS 4 |
989 | static LIST_HEAD(smi_infos); | 1016 | static LIST_HEAD(smi_infos); |
990 | static DECLARE_MUTEX(smi_infos_lock); | 1017 | static DEFINE_MUTEX(smi_infos_lock); |
991 | static int smi_num; /* Used to sequence the SMIs */ | 1018 | static int smi_num; /* Used to sequence the SMIs */ |
992 | 1019 | ||
993 | #define DEFAULT_REGSPACING 1 | 1020 | #define DEFAULT_REGSPACING 1 |
@@ -2162,9 +2189,13 @@ static void setup_xaction_handlers(struct smi_info *smi_info) | |||
2162 | 2189 | ||
2163 | static inline void wait_for_timer_and_thread(struct smi_info *smi_info) | 2190 | static inline void wait_for_timer_and_thread(struct smi_info *smi_info) |
2164 | { | 2191 | { |
2165 | if (smi_info->thread != NULL && smi_info->thread != ERR_PTR(-ENOMEM)) | 2192 | if (smi_info->intf) { |
2166 | kthread_stop(smi_info->thread); | 2193 | /* The timer and thread are only running if the |
2167 | del_timer_sync(&smi_info->si_timer); | 2194 | interface has been started up and registered. */ |
2195 | if (smi_info->thread != NULL) | ||
2196 | kthread_stop(smi_info->thread); | ||
2197 | del_timer_sync(&smi_info->si_timer); | ||
2198 | } | ||
2168 | } | 2199 | } |
2169 | 2200 | ||
2170 | static struct ipmi_default_vals | 2201 | static struct ipmi_default_vals |
@@ -2245,7 +2276,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2245 | new_smi->slave_addr, new_smi->irq); | 2276 | new_smi->slave_addr, new_smi->irq); |
2246 | } | 2277 | } |
2247 | 2278 | ||
2248 | down(&smi_infos_lock); | 2279 | mutex_lock(&smi_infos_lock); |
2249 | if (!is_new_interface(new_smi)) { | 2280 | if (!is_new_interface(new_smi)) { |
2250 | printk(KERN_WARNING "ipmi_si: duplicate interface\n"); | 2281 | printk(KERN_WARNING "ipmi_si: duplicate interface\n"); |
2251 | rv = -EBUSY; | 2282 | rv = -EBUSY; |
@@ -2341,21 +2372,6 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2341 | if (new_smi->irq) | 2372 | if (new_smi->irq) |
2342 | new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ; | 2373 | new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ; |
2343 | 2374 | ||
2344 | /* The ipmi_register_smi() code does some operations to | ||
2345 | determine the channel information, so we must be ready to | ||
2346 | handle operations before it is called. This means we have | ||
2347 | to stop the timer if we get an error after this point. */ | ||
2348 | init_timer(&(new_smi->si_timer)); | ||
2349 | new_smi->si_timer.data = (long) new_smi; | ||
2350 | new_smi->si_timer.function = smi_timeout; | ||
2351 | new_smi->last_timeout_jiffies = jiffies; | ||
2352 | new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; | ||
2353 | |||
2354 | add_timer(&(new_smi->si_timer)); | ||
2355 | if (new_smi->si_type != SI_BT) | ||
2356 | new_smi->thread = kthread_run(ipmi_thread, new_smi, | ||
2357 | "kipmi%d", new_smi->intf_num); | ||
2358 | |||
2359 | if (!new_smi->dev) { | 2375 | if (!new_smi->dev) { |
2360 | /* If we don't already have a device from something | 2376 | /* If we don't already have a device from something |
2361 | * else (like PCI), then register a new one. */ | 2377 | * else (like PCI), then register a new one. */ |
@@ -2365,7 +2381,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2365 | printk(KERN_ERR | 2381 | printk(KERN_ERR |
2366 | "ipmi_si_intf:" | 2382 | "ipmi_si_intf:" |
2367 | " Unable to allocate platform device\n"); | 2383 | " Unable to allocate platform device\n"); |
2368 | goto out_err_stop_timer; | 2384 | goto out_err; |
2369 | } | 2385 | } |
2370 | new_smi->dev = &new_smi->pdev->dev; | 2386 | new_smi->dev = &new_smi->pdev->dev; |
2371 | new_smi->dev->driver = &ipmi_driver; | 2387 | new_smi->dev->driver = &ipmi_driver; |
@@ -2377,7 +2393,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2377 | " Unable to register system interface device:" | 2393 | " Unable to register system interface device:" |
2378 | " %d\n", | 2394 | " %d\n", |
2379 | rv); | 2395 | rv); |
2380 | goto out_err_stop_timer; | 2396 | goto out_err; |
2381 | } | 2397 | } |
2382 | new_smi->dev_registered = 1; | 2398 | new_smi->dev_registered = 1; |
2383 | } | 2399 | } |
@@ -2386,8 +2402,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2386 | new_smi, | 2402 | new_smi, |
2387 | &new_smi->device_id, | 2403 | &new_smi->device_id, |
2388 | new_smi->dev, | 2404 | new_smi->dev, |
2389 | new_smi->slave_addr, | 2405 | new_smi->slave_addr); |
2390 | &(new_smi->intf)); | ||
2391 | if (rv) { | 2406 | if (rv) { |
2392 | printk(KERN_ERR | 2407 | printk(KERN_ERR |
2393 | "ipmi_si: Unable to register device: error %d\n", | 2408 | "ipmi_si: Unable to register device: error %d\n", |
@@ -2417,7 +2432,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2417 | 2432 | ||
2418 | list_add_tail(&new_smi->link, &smi_infos); | 2433 | list_add_tail(&new_smi->link, &smi_infos); |
2419 | 2434 | ||
2420 | up(&smi_infos_lock); | 2435 | mutex_unlock(&smi_infos_lock); |
2421 | 2436 | ||
2422 | printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); | 2437 | printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); |
2423 | 2438 | ||
@@ -2454,7 +2469,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2454 | 2469 | ||
2455 | kfree(new_smi); | 2470 | kfree(new_smi); |
2456 | 2471 | ||
2457 | up(&smi_infos_lock); | 2472 | mutex_unlock(&smi_infos_lock); |
2458 | 2473 | ||
2459 | return rv; | 2474 | return rv; |
2460 | } | 2475 | } |
@@ -2512,26 +2527,26 @@ static __devinit int init_ipmi_si(void) | |||
2512 | #endif | 2527 | #endif |
2513 | 2528 | ||
2514 | if (si_trydefaults) { | 2529 | if (si_trydefaults) { |
2515 | down(&smi_infos_lock); | 2530 | mutex_lock(&smi_infos_lock); |
2516 | if (list_empty(&smi_infos)) { | 2531 | if (list_empty(&smi_infos)) { |
2517 | /* No BMC was found, try defaults. */ | 2532 | /* No BMC was found, try defaults. */ |
2518 | up(&smi_infos_lock); | 2533 | mutex_unlock(&smi_infos_lock); |
2519 | default_find_bmc(); | 2534 | default_find_bmc(); |
2520 | } else { | 2535 | } else { |
2521 | up(&smi_infos_lock); | 2536 | mutex_unlock(&smi_infos_lock); |
2522 | } | 2537 | } |
2523 | } | 2538 | } |
2524 | 2539 | ||
2525 | down(&smi_infos_lock); | 2540 | mutex_lock(&smi_infos_lock); |
2526 | if (list_empty(&smi_infos)) { | 2541 | if (list_empty(&smi_infos)) { |
2527 | up(&smi_infos_lock); | 2542 | mutex_unlock(&smi_infos_lock); |
2528 | #ifdef CONFIG_PCI | 2543 | #ifdef CONFIG_PCI |
2529 | pci_unregister_driver(&ipmi_pci_driver); | 2544 | pci_unregister_driver(&ipmi_pci_driver); |
2530 | #endif | 2545 | #endif |
2531 | printk("ipmi_si: Unable to find any System Interface(s)\n"); | 2546 | printk("ipmi_si: Unable to find any System Interface(s)\n"); |
2532 | return -ENODEV; | 2547 | return -ENODEV; |
2533 | } else { | 2548 | } else { |
2534 | up(&smi_infos_lock); | 2549 | mutex_unlock(&smi_infos_lock); |
2535 | return 0; | 2550 | return 0; |
2536 | } | 2551 | } |
2537 | } | 2552 | } |
@@ -2607,10 +2622,10 @@ static __exit void cleanup_ipmi_si(void) | |||
2607 | pci_unregister_driver(&ipmi_pci_driver); | 2622 | pci_unregister_driver(&ipmi_pci_driver); |
2608 | #endif | 2623 | #endif |
2609 | 2624 | ||
2610 | down(&smi_infos_lock); | 2625 | mutex_lock(&smi_infos_lock); |
2611 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) | 2626 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) |
2612 | cleanup_one_si(e); | 2627 | cleanup_one_si(e); |
2613 | up(&smi_infos_lock); | 2628 | mutex_unlock(&smi_infos_lock); |
2614 | 2629 | ||
2615 | driver_unregister(&ipmi_driver); | 2630 | driver_unregister(&ipmi_driver); |
2616 | } | 2631 | } |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 7ece9f3c8f70..2d11ddd99e55 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/watchdog.h> | 39 | #include <linux/watchdog.h> |
40 | #include <linux/miscdevice.h> | 40 | #include <linux/miscdevice.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/completion.h> | ||
42 | #include <linux/rwsem.h> | 43 | #include <linux/rwsem.h> |
43 | #include <linux/errno.h> | 44 | #include <linux/errno.h> |
44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
@@ -303,21 +304,22 @@ static int ipmi_heartbeat(void); | |||
303 | static void panic_halt_ipmi_heartbeat(void); | 304 | static void panic_halt_ipmi_heartbeat(void); |
304 | 305 | ||
305 | 306 | ||
306 | /* We use a semaphore to make sure that only one thing can send a set | 307 | /* We use a mutex to make sure that only one thing can send a set |
307 | timeout at one time, because we only have one copy of the data. | 308 | timeout at one time, because we only have one copy of the data. |
308 | The semaphore is claimed when the set_timeout is sent and freed | 309 | The mutex is claimed when the set_timeout is sent and freed |
309 | when both messages are free. */ | 310 | when both messages are free. */ |
310 | static atomic_t set_timeout_tofree = ATOMIC_INIT(0); | 311 | static atomic_t set_timeout_tofree = ATOMIC_INIT(0); |
311 | static DECLARE_MUTEX(set_timeout_lock); | 312 | static DEFINE_MUTEX(set_timeout_lock); |
313 | static DECLARE_COMPLETION(set_timeout_wait); | ||
312 | static void set_timeout_free_smi(struct ipmi_smi_msg *msg) | 314 | static void set_timeout_free_smi(struct ipmi_smi_msg *msg) |
313 | { | 315 | { |
314 | if (atomic_dec_and_test(&set_timeout_tofree)) | 316 | if (atomic_dec_and_test(&set_timeout_tofree)) |
315 | up(&set_timeout_lock); | 317 | complete(&set_timeout_wait); |
316 | } | 318 | } |
317 | static void set_timeout_free_recv(struct ipmi_recv_msg *msg) | 319 | static void set_timeout_free_recv(struct ipmi_recv_msg *msg) |
318 | { | 320 | { |
319 | if (atomic_dec_and_test(&set_timeout_tofree)) | 321 | if (atomic_dec_and_test(&set_timeout_tofree)) |
320 | up(&set_timeout_lock); | 322 | complete(&set_timeout_wait); |
321 | } | 323 | } |
322 | static struct ipmi_smi_msg set_timeout_smi_msg = | 324 | static struct ipmi_smi_msg set_timeout_smi_msg = |
323 | { | 325 | { |
@@ -399,7 +401,7 @@ static int ipmi_set_timeout(int do_heartbeat) | |||
399 | 401 | ||
400 | 402 | ||
401 | /* We can only send one of these at a time. */ | 403 | /* We can only send one of these at a time. */ |
402 | down(&set_timeout_lock); | 404 | mutex_lock(&set_timeout_lock); |
403 | 405 | ||
404 | atomic_set(&set_timeout_tofree, 2); | 406 | atomic_set(&set_timeout_tofree, 2); |
405 | 407 | ||
@@ -407,16 +409,21 @@ static int ipmi_set_timeout(int do_heartbeat) | |||
407 | &set_timeout_recv_msg, | 409 | &set_timeout_recv_msg, |
408 | &send_heartbeat_now); | 410 | &send_heartbeat_now); |
409 | if (rv) { | 411 | if (rv) { |
410 | up(&set_timeout_lock); | 412 | mutex_unlock(&set_timeout_lock); |
411 | } else { | 413 | goto out; |
412 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) | ||
413 | || ((send_heartbeat_now) | ||
414 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) | ||
415 | { | ||
416 | rv = ipmi_heartbeat(); | ||
417 | } | ||
418 | } | 414 | } |
419 | 415 | ||
416 | wait_for_completion(&set_timeout_wait); | ||
417 | |||
418 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) | ||
419 | || ((send_heartbeat_now) | ||
420 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) | ||
421 | { | ||
422 | rv = ipmi_heartbeat(); | ||
423 | } | ||
424 | mutex_unlock(&set_timeout_lock); | ||
425 | |||
426 | out: | ||
420 | return rv; | 427 | return rv; |
421 | } | 428 | } |
422 | 429 | ||
@@ -458,17 +465,17 @@ static void panic_halt_ipmi_set_timeout(void) | |||
458 | The semaphore is claimed when the set_timeout is sent and freed | 465 | The semaphore is claimed when the set_timeout is sent and freed |
459 | when both messages are free. */ | 466 | when both messages are free. */ |
460 | static atomic_t heartbeat_tofree = ATOMIC_INIT(0); | 467 | static atomic_t heartbeat_tofree = ATOMIC_INIT(0); |
461 | static DECLARE_MUTEX(heartbeat_lock); | 468 | static DEFINE_MUTEX(heartbeat_lock); |
462 | static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock); | 469 | static DECLARE_COMPLETION(heartbeat_wait); |
463 | static void heartbeat_free_smi(struct ipmi_smi_msg *msg) | 470 | static void heartbeat_free_smi(struct ipmi_smi_msg *msg) |
464 | { | 471 | { |
465 | if (atomic_dec_and_test(&heartbeat_tofree)) | 472 | if (atomic_dec_and_test(&heartbeat_tofree)) |
466 | up(&heartbeat_wait_lock); | 473 | complete(&heartbeat_wait); |
467 | } | 474 | } |
468 | static void heartbeat_free_recv(struct ipmi_recv_msg *msg) | 475 | static void heartbeat_free_recv(struct ipmi_recv_msg *msg) |
469 | { | 476 | { |
470 | if (atomic_dec_and_test(&heartbeat_tofree)) | 477 | if (atomic_dec_and_test(&heartbeat_tofree)) |
471 | up(&heartbeat_wait_lock); | 478 | complete(&heartbeat_wait); |
472 | } | 479 | } |
473 | static struct ipmi_smi_msg heartbeat_smi_msg = | 480 | static struct ipmi_smi_msg heartbeat_smi_msg = |
474 | { | 481 | { |
@@ -511,14 +518,14 @@ static int ipmi_heartbeat(void) | |||
511 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 518 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
512 | } | 519 | } |
513 | 520 | ||
514 | down(&heartbeat_lock); | 521 | mutex_lock(&heartbeat_lock); |
515 | 522 | ||
516 | atomic_set(&heartbeat_tofree, 2); | 523 | atomic_set(&heartbeat_tofree, 2); |
517 | 524 | ||
518 | /* Don't reset the timer if we have the timer turned off, that | 525 | /* Don't reset the timer if we have the timer turned off, that |
519 | re-enables the watchdog. */ | 526 | re-enables the watchdog. */ |
520 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { | 527 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { |
521 | up(&heartbeat_lock); | 528 | mutex_unlock(&heartbeat_lock); |
522 | return 0; | 529 | return 0; |
523 | } | 530 | } |
524 | 531 | ||
@@ -539,14 +546,14 @@ static int ipmi_heartbeat(void) | |||
539 | &heartbeat_recv_msg, | 546 | &heartbeat_recv_msg, |
540 | 1); | 547 | 1); |
541 | if (rv) { | 548 | if (rv) { |
542 | up(&heartbeat_lock); | 549 | mutex_unlock(&heartbeat_lock); |
543 | printk(KERN_WARNING PFX "heartbeat failure: %d\n", | 550 | printk(KERN_WARNING PFX "heartbeat failure: %d\n", |
544 | rv); | 551 | rv); |
545 | return rv; | 552 | return rv; |
546 | } | 553 | } |
547 | 554 | ||
548 | /* Wait for the heartbeat to be sent. */ | 555 | /* Wait for the heartbeat to be sent. */ |
549 | down(&heartbeat_wait_lock); | 556 | wait_for_completion(&heartbeat_wait); |
550 | 557 | ||
551 | if (heartbeat_recv_msg.msg.data[0] != 0) { | 558 | if (heartbeat_recv_msg.msg.data[0] != 0) { |
552 | /* Got an error in the heartbeat response. It was already | 559 | /* Got an error in the heartbeat response. It was already |
@@ -555,7 +562,7 @@ static int ipmi_heartbeat(void) | |||
555 | rv = -EINVAL; | 562 | rv = -EINVAL; |
556 | } | 563 | } |
557 | 564 | ||
558 | up(&heartbeat_lock); | 565 | mutex_unlock(&heartbeat_lock); |
559 | 566 | ||
560 | return rv; | 567 | return rv; |
561 | } | 568 | } |
@@ -589,7 +596,7 @@ static void panic_halt_ipmi_heartbeat(void) | |||
589 | 1); | 596 | 1); |
590 | } | 597 | } |
591 | 598 | ||
592 | static struct watchdog_info ident= | 599 | static struct watchdog_info ident = |
593 | { | 600 | { |
594 | .options = 0, /* WDIOF_SETTIMEOUT, */ | 601 | .options = 0, /* WDIOF_SETTIMEOUT, */ |
595 | .firmware_version = 1, | 602 | .firmware_version = 1, |
@@ -790,13 +797,13 @@ static int ipmi_fasync(int fd, struct file *file, int on) | |||
790 | 797 | ||
791 | static int ipmi_close(struct inode *ino, struct file *filep) | 798 | static int ipmi_close(struct inode *ino, struct file *filep) |
792 | { | 799 | { |
793 | if (iminor(ino)==WATCHDOG_MINOR) | 800 | if (iminor(ino) == WATCHDOG_MINOR) { |
794 | { | ||
795 | if (expect_close == 42) { | 801 | if (expect_close == 42) { |
796 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | 802 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; |
797 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | 803 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); |
798 | } else { | 804 | } else { |
799 | printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); | 805 | printk(KERN_CRIT PFX |
806 | "Unexpected close, not stopping watchdog!\n"); | ||
800 | ipmi_heartbeat(); | 807 | ipmi_heartbeat(); |
801 | } | 808 | } |
802 | clear_bit(0, &ipmi_wdog_open); | 809 | clear_bit(0, &ipmi_wdog_open); |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index e5247f85a446..ef20c1fc9c4c 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -706,7 +706,6 @@ static int stli_portcmdstats(stliport_t *portp); | |||
706 | static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp); | 706 | static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp); |
707 | static int stli_getportstruct(stliport_t __user *arg); | 707 | static int stli_getportstruct(stliport_t __user *arg); |
708 | static int stli_getbrdstruct(stlibrd_t __user *arg); | 708 | static int stli_getbrdstruct(stlibrd_t __user *arg); |
709 | static void *stli_memalloc(int len); | ||
710 | static stlibrd_t *stli_allocbrd(void); | 709 | static stlibrd_t *stli_allocbrd(void); |
711 | 710 | ||
712 | static void stli_ecpinit(stlibrd_t *brdp); | 711 | static void stli_ecpinit(stlibrd_t *brdp); |
@@ -997,17 +996,6 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) | |||
997 | 996 | ||
998 | /*****************************************************************************/ | 997 | /*****************************************************************************/ |
999 | 998 | ||
1000 | /* | ||
1001 | * Local driver kernel malloc routine. | ||
1002 | */ | ||
1003 | |||
1004 | static void *stli_memalloc(int len) | ||
1005 | { | ||
1006 | return((void *) kmalloc(len, GFP_KERNEL)); | ||
1007 | } | ||
1008 | |||
1009 | /*****************************************************************************/ | ||
1010 | |||
1011 | static int stli_open(struct tty_struct *tty, struct file *filp) | 999 | static int stli_open(struct tty_struct *tty, struct file *filp) |
1012 | { | 1000 | { |
1013 | stlibrd_t *brdp; | 1001 | stlibrd_t *brdp; |
@@ -3227,13 +3215,12 @@ static int stli_initports(stlibrd_t *brdp) | |||
3227 | #endif | 3215 | #endif |
3228 | 3216 | ||
3229 | for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { | 3217 | for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { |
3230 | portp = (stliport_t *) stli_memalloc(sizeof(stliport_t)); | 3218 | portp = kzalloc(sizeof(stliport_t), GFP_KERNEL); |
3231 | if (portp == (stliport_t *) NULL) { | 3219 | if (!portp) { |
3232 | printk("STALLION: failed to allocate port structure\n"); | 3220 | printk("STALLION: failed to allocate port structure\n"); |
3233 | continue; | 3221 | continue; |
3234 | } | 3222 | } |
3235 | 3223 | ||
3236 | memset(portp, 0, sizeof(stliport_t)); | ||
3237 | portp->magic = STLI_PORTMAGIC; | 3224 | portp->magic = STLI_PORTMAGIC; |
3238 | portp->portnr = i; | 3225 | portp->portnr = i; |
3239 | portp->brdnr = brdp->brdnr; | 3226 | portp->brdnr = brdp->brdnr; |
@@ -4610,14 +4597,13 @@ static stlibrd_t *stli_allocbrd(void) | |||
4610 | { | 4597 | { |
4611 | stlibrd_t *brdp; | 4598 | stlibrd_t *brdp; |
4612 | 4599 | ||
4613 | brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t)); | 4600 | brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL); |
4614 | if (brdp == (stlibrd_t *) NULL) { | 4601 | if (!brdp) { |
4615 | printk(KERN_ERR "STALLION: failed to allocate memory " | 4602 | printk(KERN_ERR "STALLION: failed to allocate memory " |
4616 | "(size=%d)\n", sizeof(stlibrd_t)); | 4603 | "(size=%d)\n", sizeof(stlibrd_t)); |
4617 | return((stlibrd_t *) NULL); | 4604 | return NULL; |
4618 | } | 4605 | } |
4619 | 4606 | ||
4620 | memset(brdp, 0, sizeof(stlibrd_t)); | ||
4621 | brdp->magic = STLI_BOARDMAGIC; | 4607 | brdp->magic = STLI_BOARDMAGIC; |
4622 | return(brdp); | 4608 | return(brdp); |
4623 | } | 4609 | } |
@@ -5210,12 +5196,12 @@ int __init stli_init(void) | |||
5210 | /* | 5196 | /* |
5211 | * Allocate a temporary write buffer. | 5197 | * Allocate a temporary write buffer. |
5212 | */ | 5198 | */ |
5213 | stli_tmpwritebuf = (char *) stli_memalloc(STLI_TXBUFSIZE); | 5199 | stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); |
5214 | if (stli_tmpwritebuf == (char *) NULL) | 5200 | if (!stli_tmpwritebuf) |
5215 | printk(KERN_ERR "STALLION: failed to allocate memory " | 5201 | printk(KERN_ERR "STALLION: failed to allocate memory " |
5216 | "(size=%d)\n", STLI_TXBUFSIZE); | 5202 | "(size=%d)\n", STLI_TXBUFSIZE); |
5217 | stli_txcookbuf = stli_memalloc(STLI_TXBUFSIZE); | 5203 | stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); |
5218 | if (stli_txcookbuf == (char *) NULL) | 5204 | if (!stli_txcookbuf) |
5219 | printk(KERN_ERR "STALLION: failed to allocate memory " | 5205 | printk(KERN_ERR "STALLION: failed to allocate memory " |
5220 | "(size=%d)\n", STLI_TXBUFSIZE); | 5206 | "(size=%d)\n", STLI_TXBUFSIZE); |
5221 | 5207 | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 8b603b2d1c42..935670a3cd98 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -74,7 +74,7 @@ void compute_shiftstate(void); | |||
74 | k_self, k_fn, k_spec, k_pad,\ | 74 | k_self, k_fn, k_spec, k_pad,\ |
75 | k_dead, k_cons, k_cur, k_shift,\ | 75 | k_dead, k_cons, k_cur, k_shift,\ |
76 | k_meta, k_ascii, k_lock, k_lowercase,\ | 76 | k_meta, k_ascii, k_lock, k_lowercase,\ |
77 | k_slock, k_dead2, k_ignore, k_ignore | 77 | k_slock, k_dead2, k_brl, k_ignore |
78 | 78 | ||
79 | typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, | 79 | typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, |
80 | char up_flag, struct pt_regs *regs); | 80 | char up_flag, struct pt_regs *regs); |
@@ -100,7 +100,7 @@ static fn_handler_fn *fn_handler[] = { FN_HANDLERS }; | |||
100 | const int max_vals[] = { | 100 | const int max_vals[] = { |
101 | 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1, | 101 | 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1, |
102 | NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1, | 102 | NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1, |
103 | 255, NR_LOCK - 1, 255 | 103 | 255, NR_LOCK - 1, 255, NR_BRL - 1 |
104 | }; | 104 | }; |
105 | 105 | ||
106 | const int NR_TYPES = ARRAY_SIZE(max_vals); | 106 | const int NR_TYPES = ARRAY_SIZE(max_vals); |
@@ -126,7 +126,7 @@ static unsigned long key_down[NBITS(KEY_MAX)]; /* keyboard key bitmap */ | |||
126 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ | 126 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ |
127 | static int dead_key_next; | 127 | static int dead_key_next; |
128 | static int npadch = -1; /* -1 or number assembled on pad */ | 128 | static int npadch = -1; /* -1 or number assembled on pad */ |
129 | static unsigned char diacr; | 129 | static unsigned int diacr; |
130 | static char rep; /* flag telling character repeat */ | 130 | static char rep; /* flag telling character repeat */ |
131 | 131 | ||
132 | static unsigned char ledstate = 0xff; /* undefined */ | 132 | static unsigned char ledstate = 0xff; /* undefined */ |
@@ -394,22 +394,30 @@ void compute_shiftstate(void) | |||
394 | * Otherwise, conclude that DIACR was not combining after all, | 394 | * Otherwise, conclude that DIACR was not combining after all, |
395 | * queue it and return CH. | 395 | * queue it and return CH. |
396 | */ | 396 | */ |
397 | static unsigned char handle_diacr(struct vc_data *vc, unsigned char ch) | 397 | static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch) |
398 | { | 398 | { |
399 | int d = diacr; | 399 | unsigned int d = diacr; |
400 | unsigned int i; | 400 | unsigned int i; |
401 | 401 | ||
402 | diacr = 0; | 402 | diacr = 0; |
403 | 403 | ||
404 | for (i = 0; i < accent_table_size; i++) { | 404 | if ((d & ~0xff) == BRL_UC_ROW) { |
405 | if (accent_table[i].diacr == d && accent_table[i].base == ch) | 405 | if ((ch & ~0xff) == BRL_UC_ROW) |
406 | return accent_table[i].result; | 406 | return d | ch; |
407 | } else { | ||
408 | for (i = 0; i < accent_table_size; i++) | ||
409 | if (accent_table[i].diacr == d && accent_table[i].base == ch) | ||
410 | return accent_table[i].result; | ||
407 | } | 411 | } |
408 | 412 | ||
409 | if (ch == ' ' || ch == d) | 413 | if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d) |
410 | return d; | 414 | return d; |
411 | 415 | ||
412 | put_queue(vc, d); | 416 | if (kbd->kbdmode == VC_UNICODE) |
417 | to_utf8(vc, d); | ||
418 | else if (d < 0x100) | ||
419 | put_queue(vc, d); | ||
420 | |||
413 | return ch; | 421 | return ch; |
414 | } | 422 | } |
415 | 423 | ||
@@ -419,7 +427,10 @@ static unsigned char handle_diacr(struct vc_data *vc, unsigned char ch) | |||
419 | static void fn_enter(struct vc_data *vc, struct pt_regs *regs) | 427 | static void fn_enter(struct vc_data *vc, struct pt_regs *regs) |
420 | { | 428 | { |
421 | if (diacr) { | 429 | if (diacr) { |
422 | put_queue(vc, diacr); | 430 | if (kbd->kbdmode == VC_UNICODE) |
431 | to_utf8(vc, diacr); | ||
432 | else if (diacr < 0x100) | ||
433 | put_queue(vc, diacr); | ||
423 | diacr = 0; | 434 | diacr = 0; |
424 | } | 435 | } |
425 | put_queue(vc, 13); | 436 | put_queue(vc, 13); |
@@ -615,7 +626,7 @@ static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag, s | |||
615 | printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n"); | 626 | printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n"); |
616 | } | 627 | } |
617 | 628 | ||
618 | static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) | 629 | static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs) |
619 | { | 630 | { |
620 | if (up_flag) | 631 | if (up_flag) |
621 | return; /* no action, if this is a key release */ | 632 | return; /* no action, if this is a key release */ |
@@ -628,7 +639,10 @@ static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct | |||
628 | diacr = value; | 639 | diacr = value; |
629 | return; | 640 | return; |
630 | } | 641 | } |
631 | put_queue(vc, value); | 642 | if (kbd->kbdmode == VC_UNICODE) |
643 | to_utf8(vc, value); | ||
644 | else if (value < 0x100) | ||
645 | put_queue(vc, value); | ||
632 | } | 646 | } |
633 | 647 | ||
634 | /* | 648 | /* |
@@ -636,13 +650,23 @@ static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct | |||
636 | * dead keys modifying the same character. Very useful | 650 | * dead keys modifying the same character. Very useful |
637 | * for Vietnamese. | 651 | * for Vietnamese. |
638 | */ | 652 | */ |
639 | static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) | 653 | static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs) |
640 | { | 654 | { |
641 | if (up_flag) | 655 | if (up_flag) |
642 | return; | 656 | return; |
643 | diacr = (diacr ? handle_diacr(vc, value) : value); | 657 | diacr = (diacr ? handle_diacr(vc, value) : value); |
644 | } | 658 | } |
645 | 659 | ||
660 | static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) | ||
661 | { | ||
662 | k_unicode(vc, value, up_flag, regs); | ||
663 | } | ||
664 | |||
665 | static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) | ||
666 | { | ||
667 | k_deadunicode(vc, value, up_flag, regs); | ||
668 | } | ||
669 | |||
646 | /* | 670 | /* |
647 | * Obsolete - for backwards compatibility only | 671 | * Obsolete - for backwards compatibility only |
648 | */ | 672 | */ |
@@ -650,7 +674,7 @@ static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct | |||
650 | { | 674 | { |
651 | static unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; | 675 | static unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; |
652 | value = ret_diacr[value]; | 676 | value = ret_diacr[value]; |
653 | k_dead2(vc, value, up_flag, regs); | 677 | k_deadunicode(vc, value, up_flag, regs); |
654 | } | 678 | } |
655 | 679 | ||
656 | static void k_cons(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) | 680 | static void k_cons(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) |
@@ -835,6 +859,62 @@ static void k_slock(struct vc_data *vc, unsigned char value, char up_flag, struc | |||
835 | } | 859 | } |
836 | } | 860 | } |
837 | 861 | ||
862 | /* by default, 300ms interval for combination release */ | ||
863 | static long brl_timeout = 300; | ||
864 | MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for combination on first release, < 0 for dead characters)"); | ||
865 | module_param(brl_timeout, long, 0644); | ||
866 | static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs) | ||
867 | { | ||
868 | static unsigned pressed,committing; | ||
869 | static unsigned long releasestart; | ||
870 | |||
871 | if (kbd->kbdmode != VC_UNICODE) { | ||
872 | if (!up_flag) | ||
873 | printk("keyboard mode must be unicode for braille patterns\n"); | ||
874 | return; | ||
875 | } | ||
876 | |||
877 | if (!value) { | ||
878 | k_unicode(vc, BRL_UC_ROW, up_flag, regs); | ||
879 | return; | ||
880 | } | ||
881 | |||
882 | if (value > 8) | ||
883 | return; | ||
884 | |||
885 | if (brl_timeout < 0) { | ||
886 | k_deadunicode(vc, BRL_UC_ROW | (1 << (value - 1)), up_flag, regs); | ||
887 | return; | ||
888 | } | ||
889 | |||
890 | if (up_flag) { | ||
891 | if (brl_timeout) { | ||
892 | if (!committing || | ||
893 | jiffies - releasestart > (brl_timeout * HZ) / 1000) { | ||
894 | committing = pressed; | ||
895 | releasestart = jiffies; | ||
896 | } | ||
897 | pressed &= ~(1 << (value - 1)); | ||
898 | if (!pressed) { | ||
899 | if (committing) { | ||
900 | k_unicode(vc, BRL_UC_ROW | committing, 0, regs); | ||
901 | committing = 0; | ||
902 | } | ||
903 | } | ||
904 | } else { | ||
905 | if (committing) { | ||
906 | k_unicode(vc, BRL_UC_ROW | committing, 0, regs); | ||
907 | committing = 0; | ||
908 | } | ||
909 | pressed &= ~(1 << (value - 1)); | ||
910 | } | ||
911 | } else { | ||
912 | pressed |= 1 << (value - 1); | ||
913 | if (!brl_timeout) | ||
914 | committing = pressed; | ||
915 | } | ||
916 | } | ||
917 | |||
838 | /* | 918 | /* |
839 | * The leds display either (i) the status of NumLock, CapsLock, ScrollLock, | 919 | * The leds display either (i) the status of NumLock, CapsLock, ScrollLock, |
840 | * or (ii) whatever pattern of lights people want to show using KDSETLED, | 920 | * or (ii) whatever pattern of lights people want to show using KDSETLED, |
@@ -1125,9 +1205,13 @@ static void kbd_keycode(unsigned int keycode, int down, | |||
1125 | } | 1205 | } |
1126 | 1206 | ||
1127 | if (keycode > NR_KEYS) | 1207 | if (keycode > NR_KEYS) |
1128 | return; | 1208 | if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) |
1209 | keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); | ||
1210 | else | ||
1211 | return; | ||
1212 | else | ||
1213 | keysym = key_map[keycode]; | ||
1129 | 1214 | ||
1130 | keysym = key_map[keycode]; | ||
1131 | type = KTYP(keysym); | 1215 | type = KTYP(keysym); |
1132 | 1216 | ||
1133 | if (type < 0xf0) { | 1217 | if (type < 0xf0) { |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 5fdf18515433..02114a0bd0d9 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -46,7 +46,7 @@ | |||
46 | /* #define ATR_CSUM */ | 46 | /* #define ATR_CSUM */ |
47 | 47 | ||
48 | #ifdef PCMCIA_DEBUG | 48 | #ifdef PCMCIA_DEBUG |
49 | #define reader_to_dev(x) (&handle_to_dev(x->link.handle)) | 49 | #define reader_to_dev(x) (&handle_to_dev(x->p_dev->handle)) |
50 | static int pc_debug = PCMCIA_DEBUG; | 50 | static int pc_debug = PCMCIA_DEBUG; |
51 | module_param(pc_debug, int, 0600); | 51 | module_param(pc_debug, int, 0600); |
52 | #define DEBUGP(n, rdr, x, args...) do { \ | 52 | #define DEBUGP(n, rdr, x, args...) do { \ |
@@ -67,7 +67,7 @@ static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte"; | |||
67 | #define T_100MSEC msecs_to_jiffies(100) | 67 | #define T_100MSEC msecs_to_jiffies(100) |
68 | #define T_500MSEC msecs_to_jiffies(500) | 68 | #define T_500MSEC msecs_to_jiffies(500) |
69 | 69 | ||
70 | static void cm4000_release(dev_link_t *link); | 70 | static void cm4000_release(struct pcmcia_device *link); |
71 | 71 | ||
72 | static int major; /* major number we get from the kernel */ | 72 | static int major; /* major number we get from the kernel */ |
73 | 73 | ||
@@ -106,7 +106,7 @@ static int major; /* major number we get from the kernel */ | |||
106 | #define REG_STOPBITS(x) (x + 7) | 106 | #define REG_STOPBITS(x) (x + 7) |
107 | 107 | ||
108 | struct cm4000_dev { | 108 | struct cm4000_dev { |
109 | dev_link_t link; /* pcmcia link */ | 109 | struct pcmcia_device *p_dev; |
110 | dev_node_t node; /* OS node (major,minor) */ | 110 | dev_node_t node; /* OS node (major,minor) */ |
111 | 111 | ||
112 | unsigned char atr[MAX_ATR]; | 112 | unsigned char atr[MAX_ATR]; |
@@ -149,14 +149,14 @@ struct cm4000_dev { | |||
149 | #define ZERO_DEV(dev) \ | 149 | #define ZERO_DEV(dev) \ |
150 | memset(&dev->atr_csum,0, \ | 150 | memset(&dev->atr_csum,0, \ |
151 | sizeof(struct cm4000_dev) - \ | 151 | sizeof(struct cm4000_dev) - \ |
152 | /*link*/ sizeof(dev_link_t) - \ | 152 | /*link*/ sizeof(struct pcmcia_device) - \ |
153 | /*node*/ sizeof(dev_node_t) - \ | 153 | /*node*/ sizeof(dev_node_t) - \ |
154 | /*atr*/ MAX_ATR*sizeof(char) - \ | 154 | /*atr*/ MAX_ATR*sizeof(char) - \ |
155 | /*rbuf*/ 512*sizeof(char) - \ | 155 | /*rbuf*/ 512*sizeof(char) - \ |
156 | /*sbuf*/ 512*sizeof(char) - \ | 156 | /*sbuf*/ 512*sizeof(char) - \ |
157 | /*queue*/ 4*sizeof(wait_queue_head_t)) | 157 | /*queue*/ 4*sizeof(wait_queue_head_t)) |
158 | 158 | ||
159 | static dev_link_t *dev_table[CM4000_MAX_DEV]; | 159 | static struct pcmcia_device *dev_table[CM4000_MAX_DEV]; |
160 | static struct class *cmm_class; | 160 | static struct class *cmm_class; |
161 | 161 | ||
162 | /* This table doesn't use spaces after the comma between fields and thus | 162 | /* This table doesn't use spaces after the comma between fields and thus |
@@ -454,7 +454,7 @@ static struct card_fixup card_fixups[] = { | |||
454 | static void set_cardparameter(struct cm4000_dev *dev) | 454 | static void set_cardparameter(struct cm4000_dev *dev) |
455 | { | 455 | { |
456 | int i; | 456 | int i; |
457 | ioaddr_t iobase = dev->link.io.BasePort1; | 457 | ioaddr_t iobase = dev->p_dev->io.BasePort1; |
458 | u_int8_t stopbits = 0x02; /* ISO default */ | 458 | u_int8_t stopbits = 0x02; /* ISO default */ |
459 | 459 | ||
460 | DEBUGP(3, dev, "-> set_cardparameter\n"); | 460 | DEBUGP(3, dev, "-> set_cardparameter\n"); |
@@ -487,7 +487,7 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) | |||
487 | unsigned short num_bytes_read; | 487 | unsigned short num_bytes_read; |
488 | unsigned char pts_reply[4]; | 488 | unsigned char pts_reply[4]; |
489 | ssize_t rc; | 489 | ssize_t rc; |
490 | ioaddr_t iobase = dev->link.io.BasePort1; | 490 | ioaddr_t iobase = dev->p_dev->io.BasePort1; |
491 | 491 | ||
492 | rc = 0; | 492 | rc = 0; |
493 | 493 | ||
@@ -699,7 +699,7 @@ static void terminate_monitor(struct cm4000_dev *dev) | |||
699 | static void monitor_card(unsigned long p) | 699 | static void monitor_card(unsigned long p) |
700 | { | 700 | { |
701 | struct cm4000_dev *dev = (struct cm4000_dev *) p; | 701 | struct cm4000_dev *dev = (struct cm4000_dev *) p; |
702 | ioaddr_t iobase = dev->link.io.BasePort1; | 702 | ioaddr_t iobase = dev->p_dev->io.BasePort1; |
703 | unsigned short s; | 703 | unsigned short s; |
704 | struct ptsreq ptsreq; | 704 | struct ptsreq ptsreq; |
705 | int i, atrc; | 705 | int i, atrc; |
@@ -962,7 +962,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, | |||
962 | loff_t *ppos) | 962 | loff_t *ppos) |
963 | { | 963 | { |
964 | struct cm4000_dev *dev = filp->private_data; | 964 | struct cm4000_dev *dev = filp->private_data; |
965 | ioaddr_t iobase = dev->link.io.BasePort1; | 965 | ioaddr_t iobase = dev->p_dev->io.BasePort1; |
966 | ssize_t rc; | 966 | ssize_t rc; |
967 | int i, j, k; | 967 | int i, j, k; |
968 | 968 | ||
@@ -971,7 +971,7 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count, | |||
971 | if (count == 0) /* according to manpage */ | 971 | if (count == 0) /* according to manpage */ |
972 | return 0; | 972 | return 0; |
973 | 973 | ||
974 | if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */ | 974 | if (!pcmcia_dev_present(dev->p_dev) || /* device removed */ |
975 | test_bit(IS_CMM_ABSENT, &dev->flags)) | 975 | test_bit(IS_CMM_ABSENT, &dev->flags)) |
976 | return -ENODEV; | 976 | return -ENODEV; |
977 | 977 | ||
@@ -1083,7 +1083,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf, | |||
1083 | size_t count, loff_t *ppos) | 1083 | size_t count, loff_t *ppos) |
1084 | { | 1084 | { |
1085 | struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data; | 1085 | struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data; |
1086 | ioaddr_t iobase = dev->link.io.BasePort1; | 1086 | ioaddr_t iobase = dev->p_dev->io.BasePort1; |
1087 | unsigned short s; | 1087 | unsigned short s; |
1088 | unsigned char tmp; | 1088 | unsigned char tmp; |
1089 | unsigned char infolen; | 1089 | unsigned char infolen; |
@@ -1108,7 +1108,7 @@ static ssize_t cmm_write(struct file *filp, const char __user *buf, | |||
1108 | 1108 | ||
1109 | sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0; | 1109 | sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0; |
1110 | 1110 | ||
1111 | if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */ | 1111 | if (!pcmcia_dev_present(dev->p_dev) || /* device removed */ |
1112 | test_bit(IS_CMM_ABSENT, &dev->flags)) | 1112 | test_bit(IS_CMM_ABSENT, &dev->flags)) |
1113 | return -ENODEV; | 1113 | return -ENODEV; |
1114 | 1114 | ||
@@ -1440,8 +1440,8 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
1440 | unsigned long arg) | 1440 | unsigned long arg) |
1441 | { | 1441 | { |
1442 | struct cm4000_dev *dev = filp->private_data; | 1442 | struct cm4000_dev *dev = filp->private_data; |
1443 | ioaddr_t iobase = dev->link.io.BasePort1; | 1443 | ioaddr_t iobase = dev->p_dev->io.BasePort1; |
1444 | dev_link_t *link; | 1444 | struct pcmcia_device *link; |
1445 | int size; | 1445 | int size; |
1446 | int rc; | 1446 | int rc; |
1447 | void __user *argp = (void __user *)arg; | 1447 | void __user *argp = (void __user *)arg; |
@@ -1458,7 +1458,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
1458 | iminor(inode), ioctl_names[_IOC_NR(cmd)]); | 1458 | iminor(inode), ioctl_names[_IOC_NR(cmd)]); |
1459 | 1459 | ||
1460 | link = dev_table[iminor(inode)]; | 1460 | link = dev_table[iminor(inode)]; |
1461 | if (!(DEV_OK(link))) { | 1461 | if (!pcmcia_dev_present(link)) { |
1462 | DEBUGP(4, dev, "DEV_OK false\n"); | 1462 | DEBUGP(4, dev, "DEV_OK false\n"); |
1463 | return -ENODEV; | 1463 | return -ENODEV; |
1464 | } | 1464 | } |
@@ -1660,14 +1660,14 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
1660 | static int cmm_open(struct inode *inode, struct file *filp) | 1660 | static int cmm_open(struct inode *inode, struct file *filp) |
1661 | { | 1661 | { |
1662 | struct cm4000_dev *dev; | 1662 | struct cm4000_dev *dev; |
1663 | dev_link_t *link; | 1663 | struct pcmcia_device *link; |
1664 | int rc, minor = iminor(inode); | 1664 | int rc, minor = iminor(inode); |
1665 | 1665 | ||
1666 | if (minor >= CM4000_MAX_DEV) | 1666 | if (minor >= CM4000_MAX_DEV) |
1667 | return -ENODEV; | 1667 | return -ENODEV; |
1668 | 1668 | ||
1669 | link = dev_table[minor]; | 1669 | link = dev_table[minor]; |
1670 | if (link == NULL || !(DEV_OK(link))) | 1670 | if (link == NULL || !pcmcia_dev_present(link)) |
1671 | return -ENODEV; | 1671 | return -ENODEV; |
1672 | 1672 | ||
1673 | if (link->open) | 1673 | if (link->open) |
@@ -1709,7 +1709,7 @@ static int cmm_open(struct inode *inode, struct file *filp) | |||
1709 | static int cmm_close(struct inode *inode, struct file *filp) | 1709 | static int cmm_close(struct inode *inode, struct file *filp) |
1710 | { | 1710 | { |
1711 | struct cm4000_dev *dev; | 1711 | struct cm4000_dev *dev; |
1712 | dev_link_t *link; | 1712 | struct pcmcia_device *link; |
1713 | int minor = iminor(inode); | 1713 | int minor = iminor(inode); |
1714 | 1714 | ||
1715 | if (minor >= CM4000_MAX_DEV) | 1715 | if (minor >= CM4000_MAX_DEV) |
@@ -1735,7 +1735,7 @@ static int cmm_close(struct inode *inode, struct file *filp) | |||
1735 | return 0; | 1735 | return 0; |
1736 | } | 1736 | } |
1737 | 1737 | ||
1738 | static void cmm_cm4000_release(dev_link_t * link) | 1738 | static void cmm_cm4000_release(struct pcmcia_device * link) |
1739 | { | 1739 | { |
1740 | struct cm4000_dev *dev = link->priv; | 1740 | struct cm4000_dev *dev = link->priv; |
1741 | 1741 | ||
@@ -1759,13 +1759,11 @@ static void cmm_cm4000_release(dev_link_t * link) | |||
1759 | 1759 | ||
1760 | /*==== Interface to PCMCIA Layer =======================================*/ | 1760 | /*==== Interface to PCMCIA Layer =======================================*/ |
1761 | 1761 | ||
1762 | static void cm4000_config(dev_link_t * link, int devno) | 1762 | static int cm4000_config(struct pcmcia_device * link, int devno) |
1763 | { | 1763 | { |
1764 | client_handle_t handle = link->handle; | ||
1765 | struct cm4000_dev *dev; | 1764 | struct cm4000_dev *dev; |
1766 | tuple_t tuple; | 1765 | tuple_t tuple; |
1767 | cisparse_t parse; | 1766 | cisparse_t parse; |
1768 | config_info_t conf; | ||
1769 | u_char buf[64]; | 1767 | u_char buf[64]; |
1770 | int fail_fn, fail_rc; | 1768 | int fail_fn, fail_rc; |
1771 | int rc; | 1769 | int rc; |
@@ -1777,41 +1775,34 @@ static void cm4000_config(dev_link_t * link, int devno) | |||
1777 | tuple.TupleDataMax = sizeof(buf); | 1775 | tuple.TupleDataMax = sizeof(buf); |
1778 | tuple.TupleOffset = 0; | 1776 | tuple.TupleOffset = 0; |
1779 | 1777 | ||
1780 | if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) { | 1778 | if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) { |
1781 | fail_fn = GetFirstTuple; | 1779 | fail_fn = GetFirstTuple; |
1782 | goto cs_failed; | 1780 | goto cs_failed; |
1783 | } | 1781 | } |
1784 | if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) { | 1782 | if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) { |
1785 | fail_fn = GetTupleData; | 1783 | fail_fn = GetTupleData; |
1786 | goto cs_failed; | 1784 | goto cs_failed; |
1787 | } | 1785 | } |
1788 | if ((fail_rc = | 1786 | if ((fail_rc = |
1789 | pcmcia_parse_tuple(handle, &tuple, &parse)) != CS_SUCCESS) { | 1787 | pcmcia_parse_tuple(link, &tuple, &parse)) != CS_SUCCESS) { |
1790 | fail_fn = ParseTuple; | 1788 | fail_fn = ParseTuple; |
1791 | goto cs_failed; | 1789 | goto cs_failed; |
1792 | } | 1790 | } |
1793 | if ((fail_rc = | ||
1794 | pcmcia_get_configuration_info(handle, &conf)) != CS_SUCCESS) { | ||
1795 | fail_fn = GetConfigurationInfo; | ||
1796 | goto cs_failed; | ||
1797 | } | ||
1798 | 1791 | ||
1799 | link->state |= DEV_CONFIG; | ||
1800 | link->conf.ConfigBase = parse.config.base; | 1792 | link->conf.ConfigBase = parse.config.base; |
1801 | link->conf.Present = parse.config.rmask[0]; | 1793 | link->conf.Present = parse.config.rmask[0]; |
1802 | link->conf.Vcc = conf.Vcc; | ||
1803 | 1794 | ||
1804 | link->io.BasePort2 = 0; | 1795 | link->io.BasePort2 = 0; |
1805 | link->io.NumPorts2 = 0; | 1796 | link->io.NumPorts2 = 0; |
1806 | link->io.Attributes2 = 0; | 1797 | link->io.Attributes2 = 0; |
1807 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 1798 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
1808 | for (rc = pcmcia_get_first_tuple(handle, &tuple); | 1799 | for (rc = pcmcia_get_first_tuple(link, &tuple); |
1809 | rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(handle, &tuple)) { | 1800 | rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(link, &tuple)) { |
1810 | 1801 | ||
1811 | rc = pcmcia_get_tuple_data(handle, &tuple); | 1802 | rc = pcmcia_get_tuple_data(link, &tuple); |
1812 | if (rc != CS_SUCCESS) | 1803 | if (rc != CS_SUCCESS) |
1813 | continue; | 1804 | continue; |
1814 | rc = pcmcia_parse_tuple(handle, &tuple, &parse); | 1805 | rc = pcmcia_parse_tuple(link, &tuple, &parse); |
1815 | if (rc != CS_SUCCESS) | 1806 | if (rc != CS_SUCCESS) |
1816 | continue; | 1807 | continue; |
1817 | 1808 | ||
@@ -1831,7 +1822,7 @@ static void cm4000_config(dev_link_t * link, int devno) | |||
1831 | link->io.IOAddrLines = parse.cftable_entry.io.flags | 1822 | link->io.IOAddrLines = parse.cftable_entry.io.flags |
1832 | & CISTPL_IO_LINES_MASK; | 1823 | & CISTPL_IO_LINES_MASK; |
1833 | 1824 | ||
1834 | rc = pcmcia_request_io(handle, &link->io); | 1825 | rc = pcmcia_request_io(link, &link->io); |
1835 | if (rc == CS_SUCCESS) | 1826 | if (rc == CS_SUCCESS) |
1836 | break; /* we are done */ | 1827 | break; /* we are done */ |
1837 | } | 1828 | } |
@@ -1841,7 +1832,7 @@ static void cm4000_config(dev_link_t * link, int devno) | |||
1841 | link->conf.IntType = 00000002; | 1832 | link->conf.IntType = 00000002; |
1842 | 1833 | ||
1843 | if ((fail_rc = | 1834 | if ((fail_rc = |
1844 | pcmcia_request_configuration(handle, &link->conf)) != CS_SUCCESS) { | 1835 | pcmcia_request_configuration(link, &link->conf)) != CS_SUCCESS) { |
1845 | fail_fn = RequestConfiguration; | 1836 | fail_fn = RequestConfiguration; |
1846 | goto cs_release; | 1837 | goto cs_release; |
1847 | } | 1838 | } |
@@ -1851,63 +1842,48 @@ static void cm4000_config(dev_link_t * link, int devno) | |||
1851 | dev->node.major = major; | 1842 | dev->node.major = major; |
1852 | dev->node.minor = devno; | 1843 | dev->node.minor = devno; |
1853 | dev->node.next = NULL; | 1844 | dev->node.next = NULL; |
1854 | link->dev = &dev->node; | 1845 | link->dev_node = &dev->node; |
1855 | link->state &= ~DEV_CONFIG_PENDING; | ||
1856 | 1846 | ||
1857 | return; | 1847 | return 0; |
1858 | 1848 | ||
1859 | cs_failed: | 1849 | cs_failed: |
1860 | cs_error(handle, fail_fn, fail_rc); | 1850 | cs_error(link, fail_fn, fail_rc); |
1861 | cs_release: | 1851 | cs_release: |
1862 | cm4000_release(link); | 1852 | cm4000_release(link); |
1863 | 1853 | return -ENODEV; | |
1864 | link->state &= ~DEV_CONFIG_PENDING; | ||
1865 | } | 1854 | } |
1866 | 1855 | ||
1867 | static int cm4000_suspend(struct pcmcia_device *p_dev) | 1856 | static int cm4000_suspend(struct pcmcia_device *link) |
1868 | { | 1857 | { |
1869 | dev_link_t *link = dev_to_instance(p_dev); | ||
1870 | struct cm4000_dev *dev; | 1858 | struct cm4000_dev *dev; |
1871 | 1859 | ||
1872 | dev = link->priv; | 1860 | dev = link->priv; |
1873 | |||
1874 | link->state |= DEV_SUSPEND; | ||
1875 | if (link->state & DEV_CONFIG) | ||
1876 | pcmcia_release_configuration(link->handle); | ||
1877 | stop_monitor(dev); | 1861 | stop_monitor(dev); |
1878 | 1862 | ||
1879 | return 0; | 1863 | return 0; |
1880 | } | 1864 | } |
1881 | 1865 | ||
1882 | static int cm4000_resume(struct pcmcia_device *p_dev) | 1866 | static int cm4000_resume(struct pcmcia_device *link) |
1883 | { | 1867 | { |
1884 | dev_link_t *link = dev_to_instance(p_dev); | ||
1885 | struct cm4000_dev *dev; | 1868 | struct cm4000_dev *dev; |
1886 | 1869 | ||
1887 | dev = link->priv; | 1870 | dev = link->priv; |
1888 | |||
1889 | link->state &= ~DEV_SUSPEND; | ||
1890 | if (link->state & DEV_CONFIG) | ||
1891 | pcmcia_request_configuration(link->handle, &link->conf); | ||
1892 | |||
1893 | if (link->open) | 1871 | if (link->open) |
1894 | start_monitor(dev); | 1872 | start_monitor(dev); |
1895 | 1873 | ||
1896 | return 0; | 1874 | return 0; |
1897 | } | 1875 | } |
1898 | 1876 | ||
1899 | static void cm4000_release(dev_link_t *link) | 1877 | static void cm4000_release(struct pcmcia_device *link) |
1900 | { | 1878 | { |
1901 | cmm_cm4000_release(link->priv); /* delay release until device closed */ | 1879 | cmm_cm4000_release(link->priv); /* delay release until device closed */ |
1902 | pcmcia_release_configuration(link->handle); | 1880 | pcmcia_disable_device(link); |
1903 | pcmcia_release_io(link->handle, &link->io); | ||
1904 | } | 1881 | } |
1905 | 1882 | ||
1906 | static int cm4000_attach(struct pcmcia_device *p_dev) | 1883 | static int cm4000_probe(struct pcmcia_device *link) |
1907 | { | 1884 | { |
1908 | struct cm4000_dev *dev; | 1885 | struct cm4000_dev *dev; |
1909 | dev_link_t *link; | 1886 | int i, ret; |
1910 | int i; | ||
1911 | 1887 | ||
1912 | for (i = 0; i < CM4000_MAX_DEV; i++) | 1888 | for (i = 0; i < CM4000_MAX_DEV; i++) |
1913 | if (dev_table[i] == NULL) | 1889 | if (dev_table[i] == NULL) |
@@ -1923,7 +1899,7 @@ static int cm4000_attach(struct pcmcia_device *p_dev) | |||
1923 | if (dev == NULL) | 1899 | if (dev == NULL) |
1924 | return -ENOMEM; | 1900 | return -ENOMEM; |
1925 | 1901 | ||
1926 | link = &dev->link; | 1902 | dev->p_dev = link; |
1927 | link->priv = dev; | 1903 | link->priv = dev; |
1928 | link->conf.IntType = INT_MEMORY_AND_IO; | 1904 | link->conf.IntType = INT_MEMORY_AND_IO; |
1929 | dev_table[i] = link; | 1905 | dev_table[i] = link; |
@@ -1933,11 +1909,9 @@ static int cm4000_attach(struct pcmcia_device *p_dev) | |||
1933 | init_waitqueue_head(&dev->atrq); | 1909 | init_waitqueue_head(&dev->atrq); |
1934 | init_waitqueue_head(&dev->readq); | 1910 | init_waitqueue_head(&dev->readq); |
1935 | 1911 | ||
1936 | link->handle = p_dev; | 1912 | ret = cm4000_config(link, i); |
1937 | p_dev->instance = link; | 1913 | if (ret) |
1938 | 1914 | return ret; | |
1939 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
1940 | cm4000_config(link, i); | ||
1941 | 1915 | ||
1942 | class_device_create(cmm_class, NULL, MKDEV(major, i), NULL, | 1916 | class_device_create(cmm_class, NULL, MKDEV(major, i), NULL, |
1943 | "cmm%d", i); | 1917 | "cmm%d", i); |
@@ -1945,9 +1919,8 @@ static int cm4000_attach(struct pcmcia_device *p_dev) | |||
1945 | return 0; | 1919 | return 0; |
1946 | } | 1920 | } |
1947 | 1921 | ||
1948 | static void cm4000_detach(struct pcmcia_device *p_dev) | 1922 | static void cm4000_detach(struct pcmcia_device *link) |
1949 | { | 1923 | { |
1950 | dev_link_t *link = dev_to_instance(p_dev); | ||
1951 | struct cm4000_dev *dev = link->priv; | 1924 | struct cm4000_dev *dev = link->priv; |
1952 | int devno; | 1925 | int devno; |
1953 | 1926 | ||
@@ -1958,11 +1931,9 @@ static void cm4000_detach(struct pcmcia_device *p_dev) | |||
1958 | if (devno == CM4000_MAX_DEV) | 1931 | if (devno == CM4000_MAX_DEV) |
1959 | return; | 1932 | return; |
1960 | 1933 | ||
1961 | link->state &= ~DEV_PRESENT; | ||
1962 | stop_monitor(dev); | 1934 | stop_monitor(dev); |
1963 | 1935 | ||
1964 | if (link->state & DEV_CONFIG) | 1936 | cm4000_release(link); |
1965 | cm4000_release(link); | ||
1966 | 1937 | ||
1967 | dev_table[devno] = NULL; | 1938 | dev_table[devno] = NULL; |
1968 | kfree(dev); | 1939 | kfree(dev); |
@@ -1993,7 +1964,7 @@ static struct pcmcia_driver cm4000_driver = { | |||
1993 | .drv = { | 1964 | .drv = { |
1994 | .name = "cm4000_cs", | 1965 | .name = "cm4000_cs", |
1995 | }, | 1966 | }, |
1996 | .probe = cm4000_attach, | 1967 | .probe = cm4000_probe, |
1997 | .remove = cm4000_detach, | 1968 | .remove = cm4000_detach, |
1998 | .suspend = cm4000_suspend, | 1969 | .suspend = cm4000_suspend, |
1999 | .resume = cm4000_resume, | 1970 | .resume = cm4000_resume, |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 466e33bab029..29efa64580a8 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | 42 | ||
43 | #ifdef PCMCIA_DEBUG | 43 | #ifdef PCMCIA_DEBUG |
44 | #define reader_to_dev(x) (&handle_to_dev(x->link.handle)) | 44 | #define reader_to_dev(x) (&handle_to_dev(x->p_dev->handle)) |
45 | static int pc_debug = PCMCIA_DEBUG; | 45 | static int pc_debug = PCMCIA_DEBUG; |
46 | module_param(pc_debug, int, 0600); | 46 | module_param(pc_debug, int, 0600); |
47 | #define DEBUGP(n, rdr, x, args...) do { \ | 47 | #define DEBUGP(n, rdr, x, args...) do { \ |
@@ -65,7 +65,7 @@ static char *version = | |||
65 | /* how often to poll for fifo status change */ | 65 | /* how often to poll for fifo status change */ |
66 | #define POLL_PERIOD msecs_to_jiffies(10) | 66 | #define POLL_PERIOD msecs_to_jiffies(10) |
67 | 67 | ||
68 | static void reader_release(dev_link_t *link); | 68 | static void reader_release(struct pcmcia_device *link); |
69 | 69 | ||
70 | static int major; | 70 | static int major; |
71 | static struct class *cmx_class; | 71 | static struct class *cmx_class; |
@@ -74,7 +74,7 @@ static struct class *cmx_class; | |||
74 | #define BS_WRITABLE 0x02 | 74 | #define BS_WRITABLE 0x02 |
75 | 75 | ||
76 | struct reader_dev { | 76 | struct reader_dev { |
77 | dev_link_t link; | 77 | struct pcmcia_device *p_dev; |
78 | dev_node_t node; | 78 | dev_node_t node; |
79 | wait_queue_head_t devq; | 79 | wait_queue_head_t devq; |
80 | wait_queue_head_t poll_wait; | 80 | wait_queue_head_t poll_wait; |
@@ -87,7 +87,7 @@ struct reader_dev { | |||
87 | struct timer_list poll_timer; | 87 | struct timer_list poll_timer; |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static dev_link_t *dev_table[CM_MAX_DEV]; | 90 | static struct pcmcia_device *dev_table[CM_MAX_DEV]; |
91 | 91 | ||
92 | #ifndef PCMCIA_DEBUG | 92 | #ifndef PCMCIA_DEBUG |
93 | #define xoutb outb | 93 | #define xoutb outb |
@@ -116,7 +116,7 @@ static inline unsigned char xinb(unsigned short port) | |||
116 | static void cm4040_do_poll(unsigned long dummy) | 116 | static void cm4040_do_poll(unsigned long dummy) |
117 | { | 117 | { |
118 | struct reader_dev *dev = (struct reader_dev *) dummy; | 118 | struct reader_dev *dev = (struct reader_dev *) dummy; |
119 | unsigned int obs = xinb(dev->link.io.BasePort1 | 119 | unsigned int obs = xinb(dev->p_dev->io.BasePort1 |
120 | + REG_OFFSET_BUFFER_STATUS); | 120 | + REG_OFFSET_BUFFER_STATUS); |
121 | 121 | ||
122 | if ((obs & BSR_BULK_IN_FULL)) { | 122 | if ((obs & BSR_BULK_IN_FULL)) { |
@@ -147,7 +147,7 @@ static void cm4040_stop_poll(struct reader_dev *dev) | |||
147 | static int wait_for_bulk_out_ready(struct reader_dev *dev) | 147 | static int wait_for_bulk_out_ready(struct reader_dev *dev) |
148 | { | 148 | { |
149 | int i, rc; | 149 | int i, rc; |
150 | int iobase = dev->link.io.BasePort1; | 150 | int iobase = dev->p_dev->io.BasePort1; |
151 | 151 | ||
152 | for (i = 0; i < POLL_LOOP_COUNT; i++) { | 152 | for (i = 0; i < POLL_LOOP_COUNT; i++) { |
153 | if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) | 153 | if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) |
@@ -177,7 +177,7 @@ static int wait_for_bulk_out_ready(struct reader_dev *dev) | |||
177 | /* Write to Sync Control Register */ | 177 | /* Write to Sync Control Register */ |
178 | static int write_sync_reg(unsigned char val, struct reader_dev *dev) | 178 | static int write_sync_reg(unsigned char val, struct reader_dev *dev) |
179 | { | 179 | { |
180 | int iobase = dev->link.io.BasePort1; | 180 | int iobase = dev->p_dev->io.BasePort1; |
181 | int rc; | 181 | int rc; |
182 | 182 | ||
183 | rc = wait_for_bulk_out_ready(dev); | 183 | rc = wait_for_bulk_out_ready(dev); |
@@ -195,7 +195,7 @@ static int write_sync_reg(unsigned char val, struct reader_dev *dev) | |||
195 | static int wait_for_bulk_in_ready(struct reader_dev *dev) | 195 | static int wait_for_bulk_in_ready(struct reader_dev *dev) |
196 | { | 196 | { |
197 | int i, rc; | 197 | int i, rc; |
198 | int iobase = dev->link.io.BasePort1; | 198 | int iobase = dev->p_dev->io.BasePort1; |
199 | 199 | ||
200 | for (i = 0; i < POLL_LOOP_COUNT; i++) { | 200 | for (i = 0; i < POLL_LOOP_COUNT; i++) { |
201 | if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) | 201 | if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) |
@@ -225,7 +225,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, | |||
225 | size_t count, loff_t *ppos) | 225 | size_t count, loff_t *ppos) |
226 | { | 226 | { |
227 | struct reader_dev *dev = filp->private_data; | 227 | struct reader_dev *dev = filp->private_data; |
228 | int iobase = dev->link.io.BasePort1; | 228 | int iobase = dev->p_dev->io.BasePort1; |
229 | size_t bytes_to_read; | 229 | size_t bytes_to_read; |
230 | unsigned long i; | 230 | unsigned long i; |
231 | size_t min_bytes_to_read; | 231 | size_t min_bytes_to_read; |
@@ -246,7 +246,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, | |||
246 | return -EAGAIN; | 246 | return -EAGAIN; |
247 | } | 247 | } |
248 | 248 | ||
249 | if ((dev->link.state & DEV_PRESENT)==0) | 249 | if (!pcmcia_dev_present(dev->p_dev)) |
250 | return -ENODEV; | 250 | return -ENODEV; |
251 | 251 | ||
252 | for (i = 0; i < 5; i++) { | 252 | for (i = 0; i < 5; i++) { |
@@ -328,7 +328,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf, | |||
328 | size_t count, loff_t *ppos) | 328 | size_t count, loff_t *ppos) |
329 | { | 329 | { |
330 | struct reader_dev *dev = filp->private_data; | 330 | struct reader_dev *dev = filp->private_data; |
331 | int iobase = dev->link.io.BasePort1; | 331 | int iobase = dev->p_dev->io.BasePort1; |
332 | ssize_t rc; | 332 | ssize_t rc; |
333 | int i; | 333 | int i; |
334 | unsigned int bytes_to_write; | 334 | unsigned int bytes_to_write; |
@@ -351,7 +351,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf, | |||
351 | return -EAGAIN; | 351 | return -EAGAIN; |
352 | } | 352 | } |
353 | 353 | ||
354 | if ((dev->link.state & DEV_PRESENT) == 0) | 354 | if (!pcmcia_dev_present(dev->p_dev)) |
355 | return -ENODEV; | 355 | return -ENODEV; |
356 | 356 | ||
357 | bytes_to_write = count; | 357 | bytes_to_write = count; |
@@ -445,14 +445,14 @@ static unsigned int cm4040_poll(struct file *filp, poll_table *wait) | |||
445 | static int cm4040_open(struct inode *inode, struct file *filp) | 445 | static int cm4040_open(struct inode *inode, struct file *filp) |
446 | { | 446 | { |
447 | struct reader_dev *dev; | 447 | struct reader_dev *dev; |
448 | dev_link_t *link; | 448 | struct pcmcia_device *link; |
449 | int minor = iminor(inode); | 449 | int minor = iminor(inode); |
450 | 450 | ||
451 | if (minor >= CM_MAX_DEV) | 451 | if (minor >= CM_MAX_DEV) |
452 | return -ENODEV; | 452 | return -ENODEV; |
453 | 453 | ||
454 | link = dev_table[minor]; | 454 | link = dev_table[minor]; |
455 | if (link == NULL || !(DEV_OK(link))) | 455 | if (link == NULL || !pcmcia_dev_present(link)) |
456 | return -ENODEV; | 456 | return -ENODEV; |
457 | 457 | ||
458 | if (link->open) | 458 | if (link->open) |
@@ -478,7 +478,7 @@ static int cm4040_open(struct inode *inode, struct file *filp) | |||
478 | static int cm4040_close(struct inode *inode, struct file *filp) | 478 | static int cm4040_close(struct inode *inode, struct file *filp) |
479 | { | 479 | { |
480 | struct reader_dev *dev = filp->private_data; | 480 | struct reader_dev *dev = filp->private_data; |
481 | dev_link_t *link; | 481 | struct pcmcia_device *link; |
482 | int minor = iminor(inode); | 482 | int minor = iminor(inode); |
483 | 483 | ||
484 | DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode), | 484 | DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode), |
@@ -500,7 +500,7 @@ static int cm4040_close(struct inode *inode, struct file *filp) | |||
500 | return 0; | 500 | return 0; |
501 | } | 501 | } |
502 | 502 | ||
503 | static void cm4040_reader_release(dev_link_t *link) | 503 | static void cm4040_reader_release(struct pcmcia_device *link) |
504 | { | 504 | { |
505 | struct reader_dev *dev = link->priv; | 505 | struct reader_dev *dev = link->priv; |
506 | 506 | ||
@@ -514,60 +514,49 @@ static void cm4040_reader_release(dev_link_t *link) | |||
514 | return; | 514 | return; |
515 | } | 515 | } |
516 | 516 | ||
517 | static void reader_config(dev_link_t *link, int devno) | 517 | static int reader_config(struct pcmcia_device *link, int devno) |
518 | { | 518 | { |
519 | client_handle_t handle; | ||
520 | struct reader_dev *dev; | 519 | struct reader_dev *dev; |
521 | tuple_t tuple; | 520 | tuple_t tuple; |
522 | cisparse_t parse; | 521 | cisparse_t parse; |
523 | config_info_t conf; | ||
524 | u_char buf[64]; | 522 | u_char buf[64]; |
525 | int fail_fn, fail_rc; | 523 | int fail_fn, fail_rc; |
526 | int rc; | 524 | int rc; |
527 | 525 | ||
528 | handle = link->handle; | ||
529 | |||
530 | tuple.DesiredTuple = CISTPL_CONFIG; | 526 | tuple.DesiredTuple = CISTPL_CONFIG; |
531 | tuple.Attributes = 0; | 527 | tuple.Attributes = 0; |
532 | tuple.TupleData = buf; | 528 | tuple.TupleData = buf; |
533 | tuple.TupleDataMax = sizeof(buf); | 529 | tuple.TupleDataMax = sizeof(buf); |
534 | tuple.TupleOffset = 0; | 530 | tuple.TupleOffset = 0; |
535 | 531 | ||
536 | if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) { | 532 | if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) { |
537 | fail_fn = GetFirstTuple; | 533 | fail_fn = GetFirstTuple; |
538 | goto cs_failed; | 534 | goto cs_failed; |
539 | } | 535 | } |
540 | if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) { | 536 | if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) { |
541 | fail_fn = GetTupleData; | 537 | fail_fn = GetTupleData; |
542 | goto cs_failed; | 538 | goto cs_failed; |
543 | } | 539 | } |
544 | if ((fail_rc = pcmcia_parse_tuple(handle, &tuple, &parse)) | 540 | if ((fail_rc = pcmcia_parse_tuple(link, &tuple, &parse)) |
545 | != CS_SUCCESS) { | 541 | != CS_SUCCESS) { |
546 | fail_fn = ParseTuple; | 542 | fail_fn = ParseTuple; |
547 | goto cs_failed; | 543 | goto cs_failed; |
548 | } | 544 | } |
549 | if ((fail_rc = pcmcia_get_configuration_info(handle, &conf)) | ||
550 | != CS_SUCCESS) { | ||
551 | fail_fn = GetConfigurationInfo; | ||
552 | goto cs_failed; | ||
553 | } | ||
554 | 545 | ||
555 | link->state |= DEV_CONFIG; | ||
556 | link->conf.ConfigBase = parse.config.base; | 546 | link->conf.ConfigBase = parse.config.base; |
557 | link->conf.Present = parse.config.rmask[0]; | 547 | link->conf.Present = parse.config.rmask[0]; |
558 | link->conf.Vcc = conf.Vcc; | ||
559 | 548 | ||
560 | link->io.BasePort2 = 0; | 549 | link->io.BasePort2 = 0; |
561 | link->io.NumPorts2 = 0; | 550 | link->io.NumPorts2 = 0; |
562 | link->io.Attributes2 = 0; | 551 | link->io.Attributes2 = 0; |
563 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 552 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
564 | for (rc = pcmcia_get_first_tuple(handle, &tuple); | 553 | for (rc = pcmcia_get_first_tuple(link, &tuple); |
565 | rc == CS_SUCCESS; | 554 | rc == CS_SUCCESS; |
566 | rc = pcmcia_get_next_tuple(handle, &tuple)) { | 555 | rc = pcmcia_get_next_tuple(link, &tuple)) { |
567 | rc = pcmcia_get_tuple_data(handle, &tuple); | 556 | rc = pcmcia_get_tuple_data(link, &tuple); |
568 | if (rc != CS_SUCCESS) | 557 | if (rc != CS_SUCCESS) |
569 | continue; | 558 | continue; |
570 | rc = pcmcia_parse_tuple(handle, &tuple, &parse); | 559 | rc = pcmcia_parse_tuple(link, &tuple, &parse); |
571 | if (rc != CS_SUCCESS) | 560 | if (rc != CS_SUCCESS) |
572 | continue; | 561 | continue; |
573 | 562 | ||
@@ -585,13 +574,13 @@ static void reader_config(dev_link_t *link, int devno) | |||
585 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | 574 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; |
586 | link->io.IOAddrLines = parse.cftable_entry.io.flags | 575 | link->io.IOAddrLines = parse.cftable_entry.io.flags |
587 | & CISTPL_IO_LINES_MASK; | 576 | & CISTPL_IO_LINES_MASK; |
588 | rc = pcmcia_request_io(handle, &link->io); | 577 | rc = pcmcia_request_io(link, &link->io); |
589 | 578 | ||
590 | dev_printk(KERN_INFO, &handle_to_dev(handle), "foo"); | 579 | dev_printk(KERN_INFO, &handle_to_dev(link), "foo"); |
591 | if (rc == CS_SUCCESS) | 580 | if (rc == CS_SUCCESS) |
592 | break; | 581 | break; |
593 | else | 582 | else |
594 | dev_printk(KERN_INFO, &handle_to_dev(handle), | 583 | dev_printk(KERN_INFO, &handle_to_dev(link), |
595 | "pcmcia_request_io failed 0x%x\n", rc); | 584 | "pcmcia_request_io failed 0x%x\n", rc); |
596 | } | 585 | } |
597 | if (rc != CS_SUCCESS) | 586 | if (rc != CS_SUCCESS) |
@@ -599,10 +588,10 @@ static void reader_config(dev_link_t *link, int devno) | |||
599 | 588 | ||
600 | link->conf.IntType = 00000002; | 589 | link->conf.IntType = 00000002; |
601 | 590 | ||
602 | if ((fail_rc = pcmcia_request_configuration(handle,&link->conf)) | 591 | if ((fail_rc = pcmcia_request_configuration(link,&link->conf)) |
603 | !=CS_SUCCESS) { | 592 | !=CS_SUCCESS) { |
604 | fail_fn = RequestConfiguration; | 593 | fail_fn = RequestConfiguration; |
605 | dev_printk(KERN_INFO, &handle_to_dev(handle), | 594 | dev_printk(KERN_INFO, &handle_to_dev(link), |
606 | "pcmcia_request_configuration failed 0x%x\n", | 595 | "pcmcia_request_configuration failed 0x%x\n", |
607 | fail_rc); | 596 | fail_rc); |
608 | goto cs_release; | 597 | goto cs_release; |
@@ -612,57 +601,31 @@ static void reader_config(dev_link_t *link, int devno) | |||
612 | sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); | 601 | sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); |
613 | dev->node.major = major; | 602 | dev->node.major = major; |
614 | dev->node.minor = devno; | 603 | dev->node.minor = devno; |
615 | dev->node.next = NULL; | 604 | dev->node.next = &dev->node; |
616 | link->dev = &dev->node; | ||
617 | link->state &= ~DEV_CONFIG_PENDING; | ||
618 | 605 | ||
619 | DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno, | 606 | DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno, |
620 | link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1); | 607 | link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1); |
621 | DEBUGP(2, dev, "<- reader_config (succ)\n"); | 608 | DEBUGP(2, dev, "<- reader_config (succ)\n"); |
622 | 609 | ||
623 | return; | 610 | return 0; |
624 | 611 | ||
625 | cs_failed: | 612 | cs_failed: |
626 | cs_error(handle, fail_fn, fail_rc); | 613 | cs_error(link, fail_fn, fail_rc); |
627 | cs_release: | 614 | cs_release: |
628 | reader_release(link); | 615 | reader_release(link); |
629 | link->state &= ~DEV_CONFIG_PENDING; | 616 | return -ENODEV; |
630 | } | ||
631 | |||
632 | static int reader_suspend(struct pcmcia_device *p_dev) | ||
633 | { | ||
634 | dev_link_t *link = dev_to_instance(p_dev); | ||
635 | |||
636 | link->state |= DEV_SUSPEND; | ||
637 | if (link->state & DEV_CONFIG) | ||
638 | pcmcia_release_configuration(link->handle); | ||
639 | |||
640 | return 0; | ||
641 | } | 617 | } |
642 | 618 | ||
643 | static int reader_resume(struct pcmcia_device *p_dev) | 619 | static void reader_release(struct pcmcia_device *link) |
644 | { | ||
645 | dev_link_t *link = dev_to_instance(p_dev); | ||
646 | |||
647 | link->state &= ~DEV_SUSPEND; | ||
648 | if (link->state & DEV_CONFIG) | ||
649 | pcmcia_request_configuration(link->handle, &link->conf); | ||
650 | |||
651 | return 0; | ||
652 | } | ||
653 | |||
654 | static void reader_release(dev_link_t *link) | ||
655 | { | 620 | { |
656 | cm4040_reader_release(link->priv); | 621 | cm4040_reader_release(link->priv); |
657 | pcmcia_release_configuration(link->handle); | 622 | pcmcia_disable_device(link); |
658 | pcmcia_release_io(link->handle, &link->io); | ||
659 | } | 623 | } |
660 | 624 | ||
661 | static int reader_attach(struct pcmcia_device *p_dev) | 625 | static int reader_probe(struct pcmcia_device *link) |
662 | { | 626 | { |
663 | struct reader_dev *dev; | 627 | struct reader_dev *dev; |
664 | dev_link_t *link; | 628 | int i, ret; |
665 | int i; | ||
666 | 629 | ||
667 | for (i = 0; i < CM_MAX_DEV; i++) { | 630 | for (i = 0; i < CM_MAX_DEV; i++) { |
668 | if (dev_table[i] == NULL) | 631 | if (dev_table[i] == NULL) |
@@ -679,8 +642,8 @@ static int reader_attach(struct pcmcia_device *p_dev) | |||
679 | dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT; | 642 | dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT; |
680 | dev->buffer_status = 0; | 643 | dev->buffer_status = 0; |
681 | 644 | ||
682 | link = &dev->link; | ||
683 | link->priv = dev; | 645 | link->priv = dev; |
646 | dev->p_dev = link; | ||
684 | 647 | ||
685 | link->conf.IntType = INT_MEMORY_AND_IO; | 648 | link->conf.IntType = INT_MEMORY_AND_IO; |
686 | dev_table[i] = link; | 649 | dev_table[i] = link; |
@@ -692,11 +655,9 @@ static int reader_attach(struct pcmcia_device *p_dev) | |||
692 | init_timer(&dev->poll_timer); | 655 | init_timer(&dev->poll_timer); |
693 | dev->poll_timer.function = &cm4040_do_poll; | 656 | dev->poll_timer.function = &cm4040_do_poll; |
694 | 657 | ||
695 | link->handle = p_dev; | 658 | ret = reader_config(link, i); |
696 | p_dev->instance = link; | 659 | if (ret) |
697 | 660 | return ret; | |
698 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
699 | reader_config(link, i); | ||
700 | 661 | ||
701 | class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, | 662 | class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, |
702 | "cmx%d", i); | 663 | "cmx%d", i); |
@@ -704,9 +665,8 @@ static int reader_attach(struct pcmcia_device *p_dev) | |||
704 | return 0; | 665 | return 0; |
705 | } | 666 | } |
706 | 667 | ||
707 | static void reader_detach(struct pcmcia_device *p_dev) | 668 | static void reader_detach(struct pcmcia_device *link) |
708 | { | 669 | { |
709 | dev_link_t *link = dev_to_instance(p_dev); | ||
710 | struct reader_dev *dev = link->priv; | 670 | struct reader_dev *dev = link->priv; |
711 | int devno; | 671 | int devno; |
712 | 672 | ||
@@ -718,10 +678,7 @@ static void reader_detach(struct pcmcia_device *p_dev) | |||
718 | if (devno == CM_MAX_DEV) | 678 | if (devno == CM_MAX_DEV) |
719 | return; | 679 | return; |
720 | 680 | ||
721 | link->state &= ~DEV_PRESENT; | 681 | reader_release(link); |
722 | |||
723 | if (link->state & DEV_CONFIG) | ||
724 | reader_release(link); | ||
725 | 682 | ||
726 | dev_table[devno] = NULL; | 683 | dev_table[devno] = NULL; |
727 | kfree(dev); | 684 | kfree(dev); |
@@ -753,10 +710,8 @@ static struct pcmcia_driver reader_driver = { | |||
753 | .drv = { | 710 | .drv = { |
754 | .name = "cm4040_cs", | 711 | .name = "cm4040_cs", |
755 | }, | 712 | }, |
756 | .probe = reader_attach, | 713 | .probe = reader_probe, |
757 | .remove = reader_detach, | 714 | .remove = reader_detach, |
758 | .suspend = reader_suspend, | ||
759 | .resume = reader_resume, | ||
760 | .id_table = cm4040_ids, | 715 | .id_table = cm4040_ids, |
761 | }; | 716 | }; |
762 | 717 | ||
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index e6b714b6390d..07213454c458 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -228,7 +228,7 @@ typedef struct _mgslpc_info { | |||
228 | struct _input_signal_events input_signal_events; | 228 | struct _input_signal_events input_signal_events; |
229 | 229 | ||
230 | /* PCMCIA support */ | 230 | /* PCMCIA support */ |
231 | dev_link_t link; | 231 | struct pcmcia_device *p_dev; |
232 | dev_node_t node; | 232 | dev_node_t node; |
233 | int stop; | 233 | int stop; |
234 | 234 | ||
@@ -484,7 +484,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout); | |||
484 | 484 | ||
485 | /* PCMCIA prototypes */ | 485 | /* PCMCIA prototypes */ |
486 | 486 | ||
487 | static void mgslpc_config(dev_link_t *link); | 487 | static int mgslpc_config(struct pcmcia_device *link); |
488 | static void mgslpc_release(u_long arg); | 488 | static void mgslpc_release(u_long arg); |
489 | static void mgslpc_detach(struct pcmcia_device *p_dev); | 489 | static void mgslpc_detach(struct pcmcia_device *p_dev); |
490 | 490 | ||
@@ -533,14 +533,14 @@ static void ldisc_receive_buf(struct tty_struct *tty, | |||
533 | } | 533 | } |
534 | } | 534 | } |
535 | 535 | ||
536 | static int mgslpc_attach(struct pcmcia_device *p_dev) | 536 | static int mgslpc_probe(struct pcmcia_device *link) |
537 | { | 537 | { |
538 | MGSLPC_INFO *info; | 538 | MGSLPC_INFO *info; |
539 | dev_link_t *link; | 539 | int ret; |
540 | 540 | ||
541 | if (debug_level >= DEBUG_LEVEL_INFO) | 541 | if (debug_level >= DEBUG_LEVEL_INFO) |
542 | printk("mgslpc_attach\n"); | 542 | printk("mgslpc_attach\n"); |
543 | 543 | ||
544 | info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL); | 544 | info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL); |
545 | if (!info) { | 545 | if (!info) { |
546 | printk("Error can't allocate device instance data\n"); | 546 | printk("Error can't allocate device instance data\n"); |
@@ -565,25 +565,22 @@ static int mgslpc_attach(struct pcmcia_device *p_dev) | |||
565 | info->imrb_value = 0xffff; | 565 | info->imrb_value = 0xffff; |
566 | info->pim_value = 0xff; | 566 | info->pim_value = 0xff; |
567 | 567 | ||
568 | link = &info->link; | 568 | info->p_dev = link; |
569 | link->priv = info; | 569 | link->priv = info; |
570 | 570 | ||
571 | /* Initialize the dev_link_t structure */ | 571 | /* Initialize the struct pcmcia_device structure */ |
572 | 572 | ||
573 | /* Interrupt setup */ | 573 | /* Interrupt setup */ |
574 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | 574 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; |
575 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | 575 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; |
576 | link->irq.Handler = NULL; | 576 | link->irq.Handler = NULL; |
577 | 577 | ||
578 | link->conf.Attributes = 0; | 578 | link->conf.Attributes = 0; |
579 | link->conf.Vcc = 50; | ||
580 | link->conf.IntType = INT_MEMORY_AND_IO; | 579 | link->conf.IntType = INT_MEMORY_AND_IO; |
581 | 580 | ||
582 | link->handle = p_dev; | 581 | ret = mgslpc_config(link); |
583 | p_dev->instance = link; | 582 | if (ret) |
584 | 583 | return ret; | |
585 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
586 | mgslpc_config(link); | ||
587 | 584 | ||
588 | mgslpc_add_device(info); | 585 | mgslpc_add_device(info); |
589 | 586 | ||
@@ -596,15 +593,13 @@ static int mgslpc_attach(struct pcmcia_device *p_dev) | |||
596 | #define CS_CHECK(fn, ret) \ | 593 | #define CS_CHECK(fn, ret) \ |
597 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 594 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
598 | 595 | ||
599 | static void mgslpc_config(dev_link_t *link) | 596 | static int mgslpc_config(struct pcmcia_device *link) |
600 | { | 597 | { |
601 | client_handle_t handle = link->handle; | ||
602 | MGSLPC_INFO *info = link->priv; | 598 | MGSLPC_INFO *info = link->priv; |
603 | tuple_t tuple; | 599 | tuple_t tuple; |
604 | cisparse_t parse; | 600 | cisparse_t parse; |
605 | int last_fn, last_ret; | 601 | int last_fn, last_ret; |
606 | u_char buf[64]; | 602 | u_char buf[64]; |
607 | config_info_t conf; | ||
608 | cistpl_cftable_entry_t dflt = { 0 }; | 603 | cistpl_cftable_entry_t dflt = { 0 }; |
609 | cistpl_cftable_entry_t *cfg; | 604 | cistpl_cftable_entry_t *cfg; |
610 | 605 | ||
@@ -617,27 +612,20 @@ static void mgslpc_config(dev_link_t *link) | |||
617 | tuple.TupleData = buf; | 612 | tuple.TupleData = buf; |
618 | tuple.TupleDataMax = sizeof(buf); | 613 | tuple.TupleDataMax = sizeof(buf); |
619 | tuple.TupleOffset = 0; | 614 | tuple.TupleOffset = 0; |
620 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | 615 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
621 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | 616 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); |
622 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); | 617 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); |
623 | link->conf.ConfigBase = parse.config.base; | 618 | link->conf.ConfigBase = parse.config.base; |
624 | link->conf.Present = parse.config.rmask[0]; | 619 | link->conf.Present = parse.config.rmask[0]; |
625 | |||
626 | /* Configure card */ | ||
627 | link->state |= DEV_CONFIG; | ||
628 | |||
629 | /* Look up the current Vcc */ | ||
630 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); | ||
631 | link->conf.Vcc = conf.Vcc; | ||
632 | 620 | ||
633 | /* get CIS configuration entry */ | 621 | /* get CIS configuration entry */ |
634 | 622 | ||
635 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 623 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
636 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | 624 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
637 | 625 | ||
638 | cfg = &(parse.cftable_entry); | 626 | cfg = &(parse.cftable_entry); |
639 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | 627 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); |
640 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); | 628 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); |
641 | 629 | ||
642 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; | 630 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; |
643 | if (cfg->index == 0) | 631 | if (cfg->index == 0) |
@@ -658,11 +646,10 @@ static void mgslpc_config(dev_link_t *link) | |||
658 | link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | 646 | link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; |
659 | link->io.BasePort1 = io->win[0].base; | 647 | link->io.BasePort1 = io->win[0].base; |
660 | link->io.NumPorts1 = io->win[0].len; | 648 | link->io.NumPorts1 = io->win[0].len; |
661 | CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io)); | 649 | CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); |
662 | } | 650 | } |
663 | 651 | ||
664 | link->conf.Attributes = CONF_ENABLE_IRQ; | 652 | link->conf.Attributes = CONF_ENABLE_IRQ; |
665 | link->conf.Vcc = 50; | ||
666 | link->conf.IntType = INT_MEMORY_AND_IO; | 653 | link->conf.IntType = INT_MEMORY_AND_IO; |
667 | link->conf.ConfigIndex = 8; | 654 | link->conf.ConfigIndex = 8; |
668 | link->conf.Present = PRESENT_OPTION; | 655 | link->conf.Present = PRESENT_OPTION; |
@@ -670,9 +657,9 @@ static void mgslpc_config(dev_link_t *link) | |||
670 | link->irq.Attributes |= IRQ_HANDLE_PRESENT; | 657 | link->irq.Attributes |= IRQ_HANDLE_PRESENT; |
671 | link->irq.Handler = mgslpc_isr; | 658 | link->irq.Handler = mgslpc_isr; |
672 | link->irq.Instance = info; | 659 | link->irq.Instance = info; |
673 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); | 660 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
674 | 661 | ||
675 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); | 662 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); |
676 | 663 | ||
677 | info->io_base = link->io.BasePort1; | 664 | info->io_base = link->io.BasePort1; |
678 | info->irq_level = link->irq.AssignedIRQ; | 665 | info->irq_level = link->irq.AssignedIRQ; |
@@ -680,7 +667,7 @@ static void mgslpc_config(dev_link_t *link) | |||
680 | /* add to linked list of devices */ | 667 | /* add to linked list of devices */ |
681 | sprintf(info->node.dev_name, "mgslpc0"); | 668 | sprintf(info->node.dev_name, "mgslpc0"); |
682 | info->node.major = info->node.minor = 0; | 669 | info->node.major = info->node.minor = 0; |
683 | link->dev = &info->node; | 670 | link->dev_node = &info->node; |
684 | 671 | ||
685 | printk(KERN_INFO "%s: index 0x%02x:", | 672 | printk(KERN_INFO "%s: index 0x%02x:", |
686 | info->node.dev_name, link->conf.ConfigIndex); | 673 | info->node.dev_name, link->conf.ConfigIndex); |
@@ -690,13 +677,12 @@ static void mgslpc_config(dev_link_t *link) | |||
690 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | 677 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, |
691 | link->io.BasePort1+link->io.NumPorts1-1); | 678 | link->io.BasePort1+link->io.NumPorts1-1); |
692 | printk("\n"); | 679 | printk("\n"); |
693 | 680 | return 0; | |
694 | link->state &= ~DEV_CONFIG_PENDING; | ||
695 | return; | ||
696 | 681 | ||
697 | cs_failed: | 682 | cs_failed: |
698 | cs_error(link->handle, last_fn, last_ret); | 683 | cs_error(link, last_fn, last_ret); |
699 | mgslpc_release((u_long)link); | 684 | mgslpc_release((u_long)link); |
685 | return -ENODEV; | ||
700 | } | 686 | } |
701 | 687 | ||
702 | /* Card has been removed. | 688 | /* Card has been removed. |
@@ -705,58 +691,38 @@ cs_failed: | |||
705 | */ | 691 | */ |
706 | static void mgslpc_release(u_long arg) | 692 | static void mgslpc_release(u_long arg) |
707 | { | 693 | { |
708 | dev_link_t *link = (dev_link_t *)arg; | 694 | struct pcmcia_device *link = (struct pcmcia_device *)arg; |
709 | 695 | ||
710 | if (debug_level >= DEBUG_LEVEL_INFO) | 696 | if (debug_level >= DEBUG_LEVEL_INFO) |
711 | printk("mgslpc_release(0x%p)\n", link); | 697 | printk("mgslpc_release(0x%p)\n", link); |
712 | |||
713 | /* Unlink the device chain */ | ||
714 | link->dev = NULL; | ||
715 | link->state &= ~DEV_CONFIG; | ||
716 | 698 | ||
717 | pcmcia_release_configuration(link->handle); | 699 | pcmcia_disable_device(link); |
718 | if (link->io.NumPorts1) | ||
719 | pcmcia_release_io(link->handle, &link->io); | ||
720 | if (link->irq.AssignedIRQ) | ||
721 | pcmcia_release_irq(link->handle, &link->irq); | ||
722 | } | 700 | } |
723 | 701 | ||
724 | static void mgslpc_detach(struct pcmcia_device *p_dev) | 702 | static void mgslpc_detach(struct pcmcia_device *link) |
725 | { | 703 | { |
726 | dev_link_t *link = dev_to_instance(p_dev); | 704 | if (debug_level >= DEBUG_LEVEL_INFO) |
727 | 705 | printk("mgslpc_detach(0x%p)\n", link); | |
728 | if (debug_level >= DEBUG_LEVEL_INFO) | ||
729 | printk("mgslpc_detach(0x%p)\n", link); | ||
730 | 706 | ||
731 | if (link->state & DEV_CONFIG) { | 707 | ((MGSLPC_INFO *)link->priv)->stop = 1; |
732 | ((MGSLPC_INFO *)link->priv)->stop = 1; | 708 | mgslpc_release((u_long)link); |
733 | mgslpc_release((u_long)link); | ||
734 | } | ||
735 | 709 | ||
736 | mgslpc_remove_device((MGSLPC_INFO *)link->priv); | 710 | mgslpc_remove_device((MGSLPC_INFO *)link->priv); |
737 | } | 711 | } |
738 | 712 | ||
739 | static int mgslpc_suspend(struct pcmcia_device *dev) | 713 | static int mgslpc_suspend(struct pcmcia_device *link) |
740 | { | 714 | { |
741 | dev_link_t *link = dev_to_instance(dev); | ||
742 | MGSLPC_INFO *info = link->priv; | 715 | MGSLPC_INFO *info = link->priv; |
743 | 716 | ||
744 | link->state |= DEV_SUSPEND; | ||
745 | info->stop = 1; | 717 | info->stop = 1; |
746 | if (link->state & DEV_CONFIG) | ||
747 | pcmcia_release_configuration(link->handle); | ||
748 | 718 | ||
749 | return 0; | 719 | return 0; |
750 | } | 720 | } |
751 | 721 | ||
752 | static int mgslpc_resume(struct pcmcia_device *dev) | 722 | static int mgslpc_resume(struct pcmcia_device *link) |
753 | { | 723 | { |
754 | dev_link_t *link = dev_to_instance(dev); | ||
755 | MGSLPC_INFO *info = link->priv; | 724 | MGSLPC_INFO *info = link->priv; |
756 | 725 | ||
757 | link->state &= ~DEV_SUSPEND; | ||
758 | if (link->state & DEV_CONFIG) | ||
759 | pcmcia_request_configuration(link->handle, &link->conf); | ||
760 | info->stop = 0; | 726 | info->stop = 0; |
761 | 727 | ||
762 | return 0; | 728 | return 0; |
@@ -1280,7 +1246,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id, struct pt_regs * regs) | |||
1280 | if (!info) | 1246 | if (!info) |
1281 | return IRQ_NONE; | 1247 | return IRQ_NONE; |
1282 | 1248 | ||
1283 | if (!(info->link.state & DEV_CONFIG)) | 1249 | if (!(info->p_dev->_locked)) |
1284 | return IRQ_HANDLED; | 1250 | return IRQ_HANDLED; |
1285 | 1251 | ||
1286 | spin_lock(&info->lock); | 1252 | spin_lock(&info->lock); |
@@ -3033,7 +2999,7 @@ static struct pcmcia_driver mgslpc_driver = { | |||
3033 | .drv = { | 2999 | .drv = { |
3034 | .name = "synclink_cs", | 3000 | .name = "synclink_cs", |
3035 | }, | 3001 | }, |
3036 | .probe = mgslpc_attach, | 3002 | .probe = mgslpc_probe, |
3037 | .remove = mgslpc_detach, | 3003 | .remove = mgslpc_detach, |
3038 | .id_table = mgslpc_ids, | 3004 | .id_table = mgslpc_ids, |
3039 | .suspend = mgslpc_suspend, | 3005 | .suspend = mgslpc_suspend, |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 3f5d6077f39c..a9c5a7230f89 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -504,7 +504,6 @@ static int stl_echmcaintr(stlbrd_t *brdp); | |||
504 | static int stl_echpciintr(stlbrd_t *brdp); | 504 | static int stl_echpciintr(stlbrd_t *brdp); |
505 | static int stl_echpci64intr(stlbrd_t *brdp); | 505 | static int stl_echpci64intr(stlbrd_t *brdp); |
506 | static void stl_offintr(void *private); | 506 | static void stl_offintr(void *private); |
507 | static void *stl_memalloc(int len); | ||
508 | static stlbrd_t *stl_allocbrd(void); | 507 | static stlbrd_t *stl_allocbrd(void); |
509 | static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); | 508 | static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); |
510 | 509 | ||
@@ -940,17 +939,6 @@ static int stl_parsebrd(stlconf_t *confp, char **argp) | |||
940 | /*****************************************************************************/ | 939 | /*****************************************************************************/ |
941 | 940 | ||
942 | /* | 941 | /* |
943 | * Local driver kernel memory allocation routine. | ||
944 | */ | ||
945 | |||
946 | static void *stl_memalloc(int len) | ||
947 | { | ||
948 | return (void *) kmalloc(len, GFP_KERNEL); | ||
949 | } | ||
950 | |||
951 | /*****************************************************************************/ | ||
952 | |||
953 | /* | ||
954 | * Allocate a new board structure. Fill out the basic info in it. | 942 | * Allocate a new board structure. Fill out the basic info in it. |
955 | */ | 943 | */ |
956 | 944 | ||
@@ -958,14 +946,13 @@ static stlbrd_t *stl_allocbrd(void) | |||
958 | { | 946 | { |
959 | stlbrd_t *brdp; | 947 | stlbrd_t *brdp; |
960 | 948 | ||
961 | brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t)); | 949 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); |
962 | if (brdp == (stlbrd_t *) NULL) { | 950 | if (!brdp) { |
963 | printk("STALLION: failed to allocate memory (size=%d)\n", | 951 | printk("STALLION: failed to allocate memory (size=%d)\n", |
964 | sizeof(stlbrd_t)); | 952 | sizeof(stlbrd_t)); |
965 | return (stlbrd_t *) NULL; | 953 | return NULL; |
966 | } | 954 | } |
967 | 955 | ||
968 | memset(brdp, 0, sizeof(stlbrd_t)); | ||
969 | brdp->magic = STL_BOARDMAGIC; | 956 | brdp->magic = STL_BOARDMAGIC; |
970 | return brdp; | 957 | return brdp; |
971 | } | 958 | } |
@@ -1017,9 +1004,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
1017 | portp->refcount++; | 1004 | portp->refcount++; |
1018 | 1005 | ||
1019 | if ((portp->flags & ASYNC_INITIALIZED) == 0) { | 1006 | if ((portp->flags & ASYNC_INITIALIZED) == 0) { |
1020 | if (portp->tx.buf == (char *) NULL) { | 1007 | if (!portp->tx.buf) { |
1021 | portp->tx.buf = (char *) stl_memalloc(STL_TXBUFSIZE); | 1008 | portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); |
1022 | if (portp->tx.buf == (char *) NULL) | 1009 | if (!portp->tx.buf) |
1023 | return -ENOMEM; | 1010 | return -ENOMEM; |
1024 | portp->tx.head = portp->tx.buf; | 1011 | portp->tx.head = portp->tx.buf; |
1025 | portp->tx.tail = portp->tx.buf; | 1012 | portp->tx.tail = portp->tx.buf; |
@@ -2178,13 +2165,12 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
2178 | * each ports data structures. | 2165 | * each ports data structures. |
2179 | */ | 2166 | */ |
2180 | for (i = 0; (i < panelp->nrports); i++) { | 2167 | for (i = 0; (i < panelp->nrports); i++) { |
2181 | portp = (stlport_t *) stl_memalloc(sizeof(stlport_t)); | 2168 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); |
2182 | if (portp == (stlport_t *) NULL) { | 2169 | if (!portp) { |
2183 | printk("STALLION: failed to allocate memory " | 2170 | printk("STALLION: failed to allocate memory " |
2184 | "(size=%d)\n", sizeof(stlport_t)); | 2171 | "(size=%d)\n", sizeof(stlport_t)); |
2185 | break; | 2172 | break; |
2186 | } | 2173 | } |
2187 | memset(portp, 0, sizeof(stlport_t)); | ||
2188 | 2174 | ||
2189 | portp->magic = STL_PORTMAGIC; | 2175 | portp->magic = STL_PORTMAGIC; |
2190 | portp->portnr = i; | 2176 | portp->portnr = i; |
@@ -2315,13 +2301,12 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2315 | * can complete the setup. | 2301 | * can complete the setup. |
2316 | */ | 2302 | */ |
2317 | 2303 | ||
2318 | panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); | 2304 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2319 | if (panelp == (stlpanel_t *) NULL) { | 2305 | if (!panelp) { |
2320 | printk(KERN_WARNING "STALLION: failed to allocate memory " | 2306 | printk(KERN_WARNING "STALLION: failed to allocate memory " |
2321 | "(size=%d)\n", sizeof(stlpanel_t)); | 2307 | "(size=%d)\n", sizeof(stlpanel_t)); |
2322 | return(-ENOMEM); | 2308 | return -ENOMEM; |
2323 | } | 2309 | } |
2324 | memset(panelp, 0, sizeof(stlpanel_t)); | ||
2325 | 2310 | ||
2326 | panelp->magic = STL_PANELMAGIC; | 2311 | panelp->magic = STL_PANELMAGIC; |
2327 | panelp->brdnr = brdp->brdnr; | 2312 | panelp->brdnr = brdp->brdnr; |
@@ -2490,13 +2475,12 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2490 | status = inb(ioaddr + ECH_PNLSTATUS); | 2475 | status = inb(ioaddr + ECH_PNLSTATUS); |
2491 | if ((status & ECH_PNLIDMASK) != nxtid) | 2476 | if ((status & ECH_PNLIDMASK) != nxtid) |
2492 | break; | 2477 | break; |
2493 | panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); | 2478 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
2494 | if (panelp == (stlpanel_t *) NULL) { | 2479 | if (!panelp) { |
2495 | printk("STALLION: failed to allocate memory " | 2480 | printk("STALLION: failed to allocate memory " |
2496 | "(size=%d)\n", sizeof(stlpanel_t)); | 2481 | "(size=%d)\n", sizeof(stlpanel_t)); |
2497 | break; | 2482 | break; |
2498 | } | 2483 | } |
2499 | memset(panelp, 0, sizeof(stlpanel_t)); | ||
2500 | panelp->magic = STL_PANELMAGIC; | 2484 | panelp->magic = STL_PANELMAGIC; |
2501 | panelp->brdnr = brdp->brdnr; | 2485 | panelp->brdnr = brdp->brdnr; |
2502 | panelp->panelnr = panelnr; | 2486 | panelp->panelnr = panelnr; |
@@ -3074,8 +3058,8 @@ static int __init stl_init(void) | |||
3074 | /* | 3058 | /* |
3075 | * Allocate a temporary write buffer. | 3059 | * Allocate a temporary write buffer. |
3076 | */ | 3060 | */ |
3077 | stl_tmpwritebuf = (char *) stl_memalloc(STL_TXBUFSIZE); | 3061 | stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); |
3078 | if (stl_tmpwritebuf == (char *) NULL) | 3062 | if (!stl_tmpwritebuf) |
3079 | printk("STALLION: failed to allocate memory (size=%d)\n", | 3063 | printk("STALLION: failed to allocate memory (size=%d)\n", |
3080 | STL_TXBUFSIZE); | 3064 | STL_TXBUFSIZE); |
3081 | 3065 | ||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 0bfd1b63662e..98b126c2ded8 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -376,7 +376,7 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, s | |||
376 | return copied; | 376 | return copied; |
377 | } | 377 | } |
378 | 378 | ||
379 | EXPORT_SYMBOL_GPL(tty_insert_flip_string); | 379 | EXPORT_SYMBOL(tty_insert_flip_string); |
380 | 380 | ||
381 | int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) | 381 | int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) |
382 | { | 382 | { |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index ca4844c527da..acc5d47844eb 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -2328,6 +2328,10 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2328 | case TIOCL_SETVESABLANK: | 2328 | case TIOCL_SETVESABLANK: |
2329 | set_vesa_blanking(p); | 2329 | set_vesa_blanking(p); |
2330 | break; | 2330 | break; |
2331 | case TIOCL_GETKMSGREDIRECT: | ||
2332 | data = kmsg_redirect; | ||
2333 | ret = __put_user(data, p); | ||
2334 | break; | ||
2331 | case TIOCL_SETKMSGREDIRECT: | 2335 | case TIOCL_SETKMSGREDIRECT: |
2332 | if (!capable(CAP_SYS_ADMIN)) { | 2336 | if (!capable(CAP_SYS_ADMIN)) { |
2333 | ret = -EPERM; | 2337 | ret = -EPERM; |
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index 16e99db2e12d..d53f664a4dd8 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig | |||
@@ -60,6 +60,13 @@ config SOFT_WATCHDOG | |||
60 | 60 | ||
61 | # ARM Architecture | 61 | # ARM Architecture |
62 | 62 | ||
63 | config AT91_WATCHDOG | ||
64 | tristate "AT91RM9200 watchdog" | ||
65 | depends on WATCHDOG && ARCH_AT91RM9200 | ||
66 | help | ||
67 | Watchdog timer embedded into AT91RM9200 chips. This will reboot your | ||
68 | system when the timeout is reached. | ||
69 | |||
63 | config 21285_WATCHDOG | 70 | config 21285_WATCHDOG |
64 | tristate "DC21285 watchdog" | 71 | tristate "DC21285 watchdog" |
65 | depends on WATCHDOG && FOOTBRIDGE | 72 | depends on WATCHDOG && FOOTBRIDGE |
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile index d6f27fde9905..6ab77b61a643 100644 --- a/drivers/char/watchdog/Makefile +++ b/drivers/char/watchdog/Makefile | |||
@@ -23,6 +23,7 @@ obj-$(CONFIG_WDTPCI) += wdt_pci.o | |||
23 | obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o | 23 | obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o |
24 | 24 | ||
25 | # ARM Architecture | 25 | # ARM Architecture |
26 | obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o | ||
26 | obj-$(CONFIG_21285_WATCHDOG) += wdt285.o | 27 | obj-$(CONFIG_21285_WATCHDOG) += wdt285.o |
27 | obj-$(CONFIG_977_WATCHDOG) += wdt977.o | 28 | obj-$(CONFIG_977_WATCHDOG) += wdt977.o |
28 | obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o | 29 | obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o |
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91_wdt.c new file mode 100644 index 000000000000..ac83bc4b019a --- /dev/null +++ b/drivers/char/watchdog/at91_wdt.c | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * Watchdog driver for Atmel AT91RM9200 (Thunder) | ||
3 | * | ||
4 | * Copyright (C) 2003 SAN People (Pty) Ltd | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/config.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/fs.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/miscdevice.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/moduleparam.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/watchdog.h> | ||
22 | #include <asm/bitops.h> | ||
23 | #include <asm/uaccess.h> | ||
24 | |||
25 | |||
26 | #define WDT_DEFAULT_TIME 5 /* 5 seconds */ | ||
27 | #define WDT_MAX_TIME 256 /* 256 seconds */ | ||
28 | |||
29 | static int wdt_time = WDT_DEFAULT_TIME; | ||
30 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
31 | |||
32 | module_param(wdt_time, int, 0); | ||
33 | MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); | ||
34 | |||
35 | module_param(nowayout, int, 0); | ||
36 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
37 | |||
38 | |||
39 | static unsigned long at91wdt_busy; | ||
40 | |||
41 | /* ......................................................................... */ | ||
42 | |||
43 | /* | ||
44 | * Disable the watchdog. | ||
45 | */ | ||
46 | static void inline at91_wdt_stop(void) | ||
47 | { | ||
48 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Enable and reset the watchdog. | ||
53 | */ | ||
54 | static void inline at91_wdt_start(void) | ||
55 | { | ||
56 | at91_sys_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN | (((65536 * wdt_time) >> 8) & AT91_ST_WDV)); | ||
57 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * Reload the watchdog timer. (ie, pat the watchdog) | ||
62 | */ | ||
63 | static void inline at91_wdt_reload(void) | ||
64 | { | ||
65 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); | ||
66 | } | ||
67 | |||
68 | /* ......................................................................... */ | ||
69 | |||
70 | /* | ||
71 | * Watchdog device is opened, and watchdog starts running. | ||
72 | */ | ||
73 | static int at91_wdt_open(struct inode *inode, struct file *file) | ||
74 | { | ||
75 | if (test_and_set_bit(0, &at91wdt_busy)) | ||
76 | return -EBUSY; | ||
77 | |||
78 | at91_wdt_start(); | ||
79 | return nonseekable_open(inode, file); | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * Close the watchdog device. | ||
84 | * If CONFIG_WATCHDOG_NOWAYOUT is NOT defined then the watchdog is also | ||
85 | * disabled. | ||
86 | */ | ||
87 | static int at91_wdt_close(struct inode *inode, struct file *file) | ||
88 | { | ||
89 | if (!nowayout) | ||
90 | at91_wdt_stop(); /* Disable the watchdog when file is closed */ | ||
91 | |||
92 | clear_bit(0, &at91wdt_busy); | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Change the watchdog time interval. | ||
98 | */ | ||
99 | static int at91_wdt_settimeout(int new_time) | ||
100 | { | ||
101 | /* | ||
102 | * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz | ||
103 | * | ||
104 | * Since WDV is a 16-bit counter, the maximum period is | ||
105 | * 65536 / 0.256 = 256 seconds. | ||
106 | */ | ||
107 | if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) | ||
108 | return -EINVAL; | ||
109 | |||
110 | /* Set new watchdog time. It will be used when at91_wdt_start() is called. */ | ||
111 | wdt_time = new_time; | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static struct watchdog_info at91_wdt_info = { | ||
116 | .identity = "at91 watchdog", | ||
117 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | ||
118 | }; | ||
119 | |||
120 | /* | ||
121 | * Handle commands from user-space. | ||
122 | */ | ||
123 | static int at91_wdt_ioctl(struct inode *inode, struct file *file, | ||
124 | unsigned int cmd, unsigned long arg) | ||
125 | { | ||
126 | void __user *argp = (void __user *)arg; | ||
127 | int __user *p = argp; | ||
128 | int new_value; | ||
129 | |||
130 | switch(cmd) { | ||
131 | case WDIOC_KEEPALIVE: | ||
132 | at91_wdt_reload(); /* pat the watchdog */ | ||
133 | return 0; | ||
134 | |||
135 | case WDIOC_GETSUPPORT: | ||
136 | return copy_to_user(argp, &at91_wdt_info, sizeof(at91_wdt_info)) ? -EFAULT : 0; | ||
137 | |||
138 | case WDIOC_SETTIMEOUT: | ||
139 | if (get_user(new_value, p)) | ||
140 | return -EFAULT; | ||
141 | |||
142 | if (at91_wdt_settimeout(new_value)) | ||
143 | return -EINVAL; | ||
144 | |||
145 | /* Enable new time value */ | ||
146 | at91_wdt_start(); | ||
147 | |||
148 | /* Return current value */ | ||
149 | return put_user(wdt_time, p); | ||
150 | |||
151 | case WDIOC_GETTIMEOUT: | ||
152 | return put_user(wdt_time, p); | ||
153 | |||
154 | case WDIOC_GETSTATUS: | ||
155 | case WDIOC_GETBOOTSTATUS: | ||
156 | return put_user(0, p); | ||
157 | |||
158 | case WDIOC_SETOPTIONS: | ||
159 | if (get_user(new_value, p)) | ||
160 | return -EFAULT; | ||
161 | |||
162 | if (new_value & WDIOS_DISABLECARD) | ||
163 | at91_wdt_stop(); | ||
164 | if (new_value & WDIOS_ENABLECARD) | ||
165 | at91_wdt_start(); | ||
166 | return 0; | ||
167 | |||
168 | default: | ||
169 | return -ENOIOCTLCMD; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * Pat the watchdog whenever device is written to. | ||
175 | */ | ||
176 | static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) | ||
177 | { | ||
178 | at91_wdt_reload(); /* pat the watchdog */ | ||
179 | return len; | ||
180 | } | ||
181 | |||
182 | /* ......................................................................... */ | ||
183 | |||
184 | static struct file_operations at91wdt_fops = { | ||
185 | .owner = THIS_MODULE, | ||
186 | .llseek = no_llseek, | ||
187 | .ioctl = at91_wdt_ioctl, | ||
188 | .open = at91_wdt_open, | ||
189 | .release = at91_wdt_close, | ||
190 | .write = at91_wdt_write, | ||
191 | }; | ||
192 | |||
193 | static struct miscdevice at91wdt_miscdev = { | ||
194 | .minor = WATCHDOG_MINOR, | ||
195 | .name = "watchdog", | ||
196 | .fops = &at91wdt_fops, | ||
197 | }; | ||
198 | |||
199 | static int __init at91_wdt_init(void) | ||
200 | { | ||
201 | int res; | ||
202 | |||
203 | /* Check that the heartbeat value is within range; if not reset to the default */ | ||
204 | if (at91_wdt_settimeout(wdt_time)) { | ||
205 | at91_wdt_settimeout(WDT_DEFAULT_TIME); | ||
206 | printk(KERN_INFO "at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); | ||
207 | } | ||
208 | |||
209 | res = misc_register(&at91wdt_miscdev); | ||
210 | if (res) | ||
211 | return res; | ||
212 | |||
213 | printk("AT91 Watchdog Timer enabled (%d seconds, nowayout=%d)\n", wdt_time, nowayout); | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static void __exit at91_wdt_exit(void) | ||
218 | { | ||
219 | misc_deregister(&at91wdt_miscdev); | ||
220 | } | ||
221 | |||
222 | module_init(at91_wdt_init); | ||
223 | module_exit(at91_wdt_exit); | ||
224 | |||
225 | MODULE_AUTHOR("Andrew Victor"); | ||
226 | MODULE_DESCRIPTION("Watchdog driver for Atmel AT91RM9200"); | ||
227 | MODULE_LICENSE("GPL"); | ||
228 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c index 8d6b249ad66b..6d44ca68312d 100644 --- a/drivers/char/watchdog/pcwd.c +++ b/drivers/char/watchdog/pcwd.c | |||
@@ -66,15 +66,13 @@ | |||
66 | #include <linux/fs.h> /* For file operations */ | 66 | #include <linux/fs.h> /* For file operations */ |
67 | #include <linux/ioport.h> /* For io-port access */ | 67 | #include <linux/ioport.h> /* For io-port access */ |
68 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | 68 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
69 | #include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */ | ||
70 | #include <linux/slab.h> /* For kmalloc */ | ||
71 | 69 | ||
72 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | 70 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ |
73 | #include <asm/io.h> /* For inb/outb/... */ | 71 | #include <asm/io.h> /* For inb/outb/... */ |
74 | 72 | ||
75 | /* Module and version information */ | 73 | /* Module and version information */ |
76 | #define WATCHDOG_VERSION "1.16" | 74 | #define WATCHDOG_VERSION "1.17" |
77 | #define WATCHDOG_DATE "03 Jan 2006" | 75 | #define WATCHDOG_DATE "12 Feb 2006" |
78 | #define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" | 76 | #define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" |
79 | #define WATCHDOG_NAME "pcwd" | 77 | #define WATCHDOG_NAME "pcwd" |
80 | #define PFX WATCHDOG_NAME ": " | 78 | #define PFX WATCHDOG_NAME ": " |
@@ -96,15 +94,19 @@ | |||
96 | * PCI-PC Watchdog card. | 94 | * PCI-PC Watchdog card. |
97 | */ | 95 | */ |
98 | /* Port 1 : Control Status #1 for the PC Watchdog card, revision A. */ | 96 | /* Port 1 : Control Status #1 for the PC Watchdog card, revision A. */ |
99 | #define WD_WDRST 0x01 /* Previously reset state */ | 97 | #define WD_WDRST 0x01 /* Previously reset state */ |
100 | #define WD_T110 0x02 /* Temperature overheat sense */ | 98 | #define WD_T110 0x02 /* Temperature overheat sense */ |
101 | #define WD_HRTBT 0x04 /* Heartbeat sense */ | 99 | #define WD_HRTBT 0x04 /* Heartbeat sense */ |
102 | #define WD_RLY2 0x08 /* External relay triggered */ | 100 | #define WD_RLY2 0x08 /* External relay triggered */ |
103 | #define WD_SRLY2 0x80 /* Software external relay triggered */ | 101 | #define WD_SRLY2 0x80 /* Software external relay triggered */ |
104 | /* Port 1 : Control Status #1 for the PC Watchdog card, revision C. */ | 102 | /* Port 1 : Control Status #1 for the PC Watchdog card, revision C. */ |
105 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ | 103 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ |
106 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ | 104 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ |
107 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ | 105 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ |
106 | #define WD_REVC_RL2A 0x08 /* Relay 2 activated by on-board processor */ | ||
107 | #define WD_REVC_RL1A 0x10 /* Relay 1 active */ | ||
108 | #define WD_REVC_R2DS 0x40 /* Relay 2 disable */ | ||
109 | #define WD_REVC_RLY2 0x80 /* Relay 2 activated? */ | ||
108 | /* Port 2 : Control Status #2 */ | 110 | /* Port 2 : Control Status #2 */ |
109 | #define WD_WDIS 0x10 /* Watchdog Disabled */ | 111 | #define WD_WDIS 0x10 /* Watchdog Disabled */ |
110 | #define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ | 112 | #define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ |
@@ -122,9 +124,14 @@ | |||
122 | #define CMD_ISA_VERSION_HUNDRETH 0x03 | 124 | #define CMD_ISA_VERSION_HUNDRETH 0x03 |
123 | #define CMD_ISA_VERSION_MINOR 0x04 | 125 | #define CMD_ISA_VERSION_MINOR 0x04 |
124 | #define CMD_ISA_SWITCH_SETTINGS 0x05 | 126 | #define CMD_ISA_SWITCH_SETTINGS 0x05 |
127 | #define CMD_ISA_RESET_PC 0x06 | ||
128 | #define CMD_ISA_ARM_0 0x07 | ||
129 | #define CMD_ISA_ARM_30 0x08 | ||
130 | #define CMD_ISA_ARM_60 0x09 | ||
125 | #define CMD_ISA_DELAY_TIME_2SECS 0x0A | 131 | #define CMD_ISA_DELAY_TIME_2SECS 0x0A |
126 | #define CMD_ISA_DELAY_TIME_4SECS 0x0B | 132 | #define CMD_ISA_DELAY_TIME_4SECS 0x0B |
127 | #define CMD_ISA_DELAY_TIME_8SECS 0x0C | 133 | #define CMD_ISA_DELAY_TIME_8SECS 0x0C |
134 | #define CMD_ISA_RESET_RELAYS 0x0D | ||
128 | 135 | ||
129 | /* | 136 | /* |
130 | * We are using an kernel timer to do the pinging of the watchdog | 137 | * We are using an kernel timer to do the pinging of the watchdog |
@@ -142,6 +149,7 @@ static atomic_t open_allowed = ATOMIC_INIT(1); | |||
142 | static char expect_close; | 149 | static char expect_close; |
143 | static int temp_panic; | 150 | static int temp_panic; |
144 | static struct { /* this is private data for each ISA-PC watchdog card */ | 151 | static struct { /* this is private data for each ISA-PC watchdog card */ |
152 | char fw_ver_str[6]; /* The cards firmware version */ | ||
145 | int revision; /* The card's revision */ | 153 | int revision; /* The card's revision */ |
146 | int supports_temp; /* Wether or not the card has a temperature device */ | 154 | int supports_temp; /* Wether or not the card has a temperature device */ |
147 | int command_mode; /* Wether or not the card is in command mode */ | 155 | int command_mode; /* Wether or not the card is in command mode */ |
@@ -153,6 +161,13 @@ static struct { /* this is private data for each ISA-PC watchdog card */ | |||
153 | } pcwd_private; | 161 | } pcwd_private; |
154 | 162 | ||
155 | /* module parameters */ | 163 | /* module parameters */ |
164 | #define QUIET 0 /* Default */ | ||
165 | #define VERBOSE 1 /* Verbose */ | ||
166 | #define DEBUG 2 /* print fancy stuff too */ | ||
167 | static int debug = QUIET; | ||
168 | module_param(debug, int, 0); | ||
169 | MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)"); | ||
170 | |||
156 | #define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ | 171 | #define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ |
157 | static int heartbeat = WATCHDOG_HEARTBEAT; | 172 | static int heartbeat = WATCHDOG_HEARTBEAT; |
158 | module_param(heartbeat, int, 0); | 173 | module_param(heartbeat, int, 0); |
@@ -172,6 +187,10 @@ static int send_isa_command(int cmd) | |||
172 | int control_status; | 187 | int control_status; |
173 | int port0, last_port0; /* Double read for stabilising */ | 188 | int port0, last_port0; /* Double read for stabilising */ |
174 | 189 | ||
190 | if (debug >= DEBUG) | ||
191 | printk(KERN_DEBUG PFX "sending following data cmd=0x%02x\n", | ||
192 | cmd); | ||
193 | |||
175 | /* The WCMD bit must be 1 and the command is only 4 bits in size */ | 194 | /* The WCMD bit must be 1 and the command is only 4 bits in size */ |
176 | control_status = (cmd & 0x0F) | WD_WCMD; | 195 | control_status = (cmd & 0x0F) | WD_WCMD; |
177 | outb_p(control_status, pcwd_private.io_addr + 2); | 196 | outb_p(control_status, pcwd_private.io_addr + 2); |
@@ -188,6 +207,10 @@ static int send_isa_command(int cmd) | |||
188 | udelay (250); | 207 | udelay (250); |
189 | } | 208 | } |
190 | 209 | ||
210 | if (debug >= DEBUG) | ||
211 | printk(KERN_DEBUG PFX "received following data for cmd=0x%02x: port0=0x%02x last_port0=0x%02x\n", | ||
212 | cmd, port0, last_port0); | ||
213 | |||
191 | return port0; | 214 | return port0; |
192 | } | 215 | } |
193 | 216 | ||
@@ -214,6 +237,10 @@ static int set_command_mode(void) | |||
214 | spin_unlock(&pcwd_private.io_lock); | 237 | spin_unlock(&pcwd_private.io_lock); |
215 | pcwd_private.command_mode = found; | 238 | pcwd_private.command_mode = found; |
216 | 239 | ||
240 | if (debug >= DEBUG) | ||
241 | printk(KERN_DEBUG PFX "command_mode=%d\n", | ||
242 | pcwd_private.command_mode); | ||
243 | |||
217 | return(found); | 244 | return(found); |
218 | } | 245 | } |
219 | 246 | ||
@@ -226,6 +253,10 @@ static void unset_command_mode(void) | |||
226 | spin_unlock(&pcwd_private.io_lock); | 253 | spin_unlock(&pcwd_private.io_lock); |
227 | 254 | ||
228 | pcwd_private.command_mode = 0; | 255 | pcwd_private.command_mode = 0; |
256 | |||
257 | if (debug >= DEBUG) | ||
258 | printk(KERN_DEBUG PFX "command_mode=%d\n", | ||
259 | pcwd_private.command_mode); | ||
229 | } | 260 | } |
230 | 261 | ||
231 | static inline void pcwd_check_temperature_support(void) | 262 | static inline void pcwd_check_temperature_support(void) |
@@ -234,27 +265,22 @@ static inline void pcwd_check_temperature_support(void) | |||
234 | pcwd_private.supports_temp = 1; | 265 | pcwd_private.supports_temp = 1; |
235 | } | 266 | } |
236 | 267 | ||
237 | static inline char *get_firmware(void) | 268 | static inline void pcwd_get_firmware(void) |
238 | { | 269 | { |
239 | int one, ten, hund, minor; | 270 | int one, ten, hund, minor; |
240 | char *ret; | ||
241 | 271 | ||
242 | ret = kmalloc(6, GFP_KERNEL); | 272 | strcpy(pcwd_private.fw_ver_str, "ERROR"); |
243 | if(ret == NULL) | ||
244 | return NULL; | ||
245 | 273 | ||
246 | if (set_command_mode()) { | 274 | if (set_command_mode()) { |
247 | one = send_isa_command(CMD_ISA_VERSION_INTEGER); | 275 | one = send_isa_command(CMD_ISA_VERSION_INTEGER); |
248 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); | 276 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); |
249 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); | 277 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); |
250 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); | 278 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); |
251 | sprintf(ret, "%c.%c%c%c", one, ten, hund, minor); | 279 | sprintf(pcwd_private.fw_ver_str, "%c.%c%c%c", one, ten, hund, minor); |
252 | } | 280 | } |
253 | else | ||
254 | sprintf(ret, "ERROR"); | ||
255 | |||
256 | unset_command_mode(); | 281 | unset_command_mode(); |
257 | return(ret); | 282 | |
283 | return; | ||
258 | } | 284 | } |
259 | 285 | ||
260 | static inline int pcwd_get_option_switches(void) | 286 | static inline int pcwd_get_option_switches(void) |
@@ -272,17 +298,15 @@ static inline int pcwd_get_option_switches(void) | |||
272 | 298 | ||
273 | static void pcwd_show_card_info(void) | 299 | static void pcwd_show_card_info(void) |
274 | { | 300 | { |
275 | char *firmware; | ||
276 | int option_switches; | 301 | int option_switches; |
277 | 302 | ||
278 | /* Get some extra info from the hardware (in command/debug/diag mode) */ | 303 | /* Get some extra info from the hardware (in command/debug/diag mode) */ |
279 | if (pcwd_private.revision == PCWD_REVISION_A) | 304 | if (pcwd_private.revision == PCWD_REVISION_A) |
280 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); | 305 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); |
281 | else if (pcwd_private.revision == PCWD_REVISION_C) { | 306 | else if (pcwd_private.revision == PCWD_REVISION_C) { |
282 | firmware = get_firmware(); | 307 | pcwd_get_firmware(); |
283 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", | 308 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", |
284 | pcwd_private.io_addr, firmware); | 309 | pcwd_private.io_addr, pcwd_private.fw_ver_str); |
285 | kfree(firmware); | ||
286 | option_switches = pcwd_get_option_switches(); | 310 | option_switches = pcwd_get_option_switches(); |
287 | printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", | 311 | printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", |
288 | option_switches, | 312 | option_switches, |
@@ -362,6 +386,10 @@ static int pcwd_start(void) | |||
362 | return -EIO; | 386 | return -EIO; |
363 | } | 387 | } |
364 | } | 388 | } |
389 | |||
390 | if (debug >= VERBOSE) | ||
391 | printk(KERN_DEBUG PFX "Watchdog started\n"); | ||
392 | |||
365 | return 0; | 393 | return 0; |
366 | } | 394 | } |
367 | 395 | ||
@@ -386,6 +414,10 @@ static int pcwd_stop(void) | |||
386 | return -EIO; | 414 | return -EIO; |
387 | } | 415 | } |
388 | } | 416 | } |
417 | |||
418 | if (debug >= VERBOSE) | ||
419 | printk(KERN_DEBUG PFX "Watchdog stopped\n"); | ||
420 | |||
389 | return 0; | 421 | return 0; |
390 | } | 422 | } |
391 | 423 | ||
@@ -393,6 +425,10 @@ static int pcwd_keepalive(void) | |||
393 | { | 425 | { |
394 | /* user land ping */ | 426 | /* user land ping */ |
395 | pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ); | 427 | pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ); |
428 | |||
429 | if (debug >= DEBUG) | ||
430 | printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n"); | ||
431 | |||
396 | return 0; | 432 | return 0; |
397 | } | 433 | } |
398 | 434 | ||
@@ -402,12 +438,17 @@ static int pcwd_set_heartbeat(int t) | |||
402 | return -EINVAL; | 438 | return -EINVAL; |
403 | 439 | ||
404 | heartbeat = t; | 440 | heartbeat = t; |
441 | |||
442 | if (debug >= VERBOSE) | ||
443 | printk(KERN_DEBUG PFX "New heartbeat: %d\n", | ||
444 | heartbeat); | ||
445 | |||
405 | return 0; | 446 | return 0; |
406 | } | 447 | } |
407 | 448 | ||
408 | static int pcwd_get_status(int *status) | 449 | static int pcwd_get_status(int *status) |
409 | { | 450 | { |
410 | int card_status; | 451 | int control_status; |
411 | 452 | ||
412 | *status=0; | 453 | *status=0; |
413 | spin_lock(&pcwd_private.io_lock); | 454 | spin_lock(&pcwd_private.io_lock); |
@@ -415,37 +456,39 @@ static int pcwd_get_status(int *status) | |||
415 | /* Rev A cards return status information from | 456 | /* Rev A cards return status information from |
416 | * the base register, which is used for the | 457 | * the base register, which is used for the |
417 | * temperature in other cards. */ | 458 | * temperature in other cards. */ |
418 | card_status = inb(pcwd_private.io_addr); | 459 | control_status = inb(pcwd_private.io_addr); |
419 | else { | 460 | else { |
420 | /* Rev C cards return card status in the base | 461 | /* Rev C cards return card status in the base |
421 | * address + 1 register. And use different bits | 462 | * address + 1 register. And use different bits |
422 | * to indicate a card initiated reset, and an | 463 | * to indicate a card initiated reset, and an |
423 | * over-temperature condition. And the reboot | 464 | * over-temperature condition. And the reboot |
424 | * status can be reset. */ | 465 | * status can be reset. */ |
425 | card_status = inb(pcwd_private.io_addr + 1); | 466 | control_status = inb(pcwd_private.io_addr + 1); |
426 | } | 467 | } |
427 | spin_unlock(&pcwd_private.io_lock); | 468 | spin_unlock(&pcwd_private.io_lock); |
428 | 469 | ||
429 | if (pcwd_private.revision == PCWD_REVISION_A) { | 470 | if (pcwd_private.revision == PCWD_REVISION_A) { |
430 | if (card_status & WD_WDRST) | 471 | if (control_status & WD_WDRST) |
431 | *status |= WDIOF_CARDRESET; | 472 | *status |= WDIOF_CARDRESET; |
432 | 473 | ||
433 | if (card_status & WD_T110) { | 474 | if (control_status & WD_T110) { |
434 | *status |= WDIOF_OVERHEAT; | 475 | *status |= WDIOF_OVERHEAT; |
435 | if (temp_panic) { | 476 | if (temp_panic) { |
436 | printk (KERN_INFO PFX "Temperature overheat trip!\n"); | 477 | printk (KERN_INFO PFX "Temperature overheat trip!\n"); |
437 | kernel_power_off(); | 478 | kernel_power_off(); |
479 | /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */ | ||
438 | } | 480 | } |
439 | } | 481 | } |
440 | } else { | 482 | } else { |
441 | if (card_status & WD_REVC_WTRP) | 483 | if (control_status & WD_REVC_WTRP) |
442 | *status |= WDIOF_CARDRESET; | 484 | *status |= WDIOF_CARDRESET; |
443 | 485 | ||
444 | if (card_status & WD_REVC_TTRP) { | 486 | if (control_status & WD_REVC_TTRP) { |
445 | *status |= WDIOF_OVERHEAT; | 487 | *status |= WDIOF_OVERHEAT; |
446 | if (temp_panic) { | 488 | if (temp_panic) { |
447 | printk (KERN_INFO PFX "Temperature overheat trip!\n"); | 489 | printk (KERN_INFO PFX "Temperature overheat trip!\n"); |
448 | kernel_power_off(); | 490 | kernel_power_off(); |
491 | /* or should we just do a: panic(PFX "Temperature overheat trip!\n"); */ | ||
449 | } | 492 | } |
450 | } | 493 | } |
451 | } | 494 | } |
@@ -455,9 +498,25 @@ static int pcwd_get_status(int *status) | |||
455 | 498 | ||
456 | static int pcwd_clear_status(void) | 499 | static int pcwd_clear_status(void) |
457 | { | 500 | { |
501 | int control_status; | ||
502 | |||
458 | if (pcwd_private.revision == PCWD_REVISION_C) { | 503 | if (pcwd_private.revision == PCWD_REVISION_C) { |
459 | spin_lock(&pcwd_private.io_lock); | 504 | spin_lock(&pcwd_private.io_lock); |
460 | outb_p(0x00, pcwd_private.io_addr + 1); /* clear reset status */ | 505 | |
506 | if (debug >= VERBOSE) | ||
507 | printk(KERN_INFO PFX "clearing watchdog trip status\n"); | ||
508 | |||
509 | control_status = inb_p(pcwd_private.io_addr + 1); | ||
510 | |||
511 | if (debug >= DEBUG) { | ||
512 | printk(KERN_DEBUG PFX "status was: 0x%02x\n", control_status); | ||
513 | printk(KERN_DEBUG PFX "sending: 0x%02x\n", | ||
514 | (control_status & WD_REVC_R2DS)); | ||
515 | } | ||
516 | |||
517 | /* clear reset status & Keep Relay 2 disable state as it is */ | ||
518 | outb_p((control_status & WD_REVC_R2DS), pcwd_private.io_addr + 1); | ||
519 | |||
461 | spin_unlock(&pcwd_private.io_lock); | 520 | spin_unlock(&pcwd_private.io_lock); |
462 | } | 521 | } |
463 | return 0; | 522 | return 0; |
@@ -481,6 +540,11 @@ static int pcwd_get_temperature(int *temperature) | |||
481 | *temperature = ((inb(pcwd_private.io_addr)) * 9 / 5) + 32; | 540 | *temperature = ((inb(pcwd_private.io_addr)) * 9 / 5) + 32; |
482 | spin_unlock(&pcwd_private.io_lock); | 541 | spin_unlock(&pcwd_private.io_lock); |
483 | 542 | ||
543 | if (debug >= DEBUG) { | ||
544 | printk(KERN_DEBUG PFX "temperature is: %d F\n", | ||
545 | *temperature); | ||
546 | } | ||
547 | |||
484 | return 0; | 548 | return 0; |
485 | } | 549 | } |
486 | 550 | ||
@@ -599,6 +663,8 @@ static ssize_t pcwd_write(struct file *file, const char __user *buf, size_t len, | |||
599 | static int pcwd_open(struct inode *inode, struct file *file) | 663 | static int pcwd_open(struct inode *inode, struct file *file) |
600 | { | 664 | { |
601 | if (!atomic_dec_and_test(&open_allowed) ) { | 665 | if (!atomic_dec_and_test(&open_allowed) ) { |
666 | if (debug >= VERBOSE) | ||
667 | printk(KERN_ERR PFX "Attempt to open already opened device.\n"); | ||
602 | atomic_inc( &open_allowed ); | 668 | atomic_inc( &open_allowed ); |
603 | return -EBUSY; | 669 | return -EBUSY; |
604 | } | 670 | } |
@@ -922,7 +988,8 @@ static void __exit pcwd_cleanup_module(void) | |||
922 | { | 988 | { |
923 | if (pcwd_private.io_addr) | 989 | if (pcwd_private.io_addr) |
924 | pcwatchdog_exit(); | 990 | pcwatchdog_exit(); |
925 | return; | 991 | |
992 | printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); | ||
926 | } | 993 | } |
927 | 994 | ||
928 | module_init(pcwd_init_module); | 995 | module_init(pcwd_init_module); |
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index 2700c5c45b8a..3fdfda9324fa 100644 --- a/drivers/char/watchdog/pcwd_usb.c +++ b/drivers/char/watchdog/pcwd_usb.c | |||
@@ -705,7 +705,8 @@ err_out_misc_deregister: | |||
705 | err_out_unregister_reboot: | 705 | err_out_unregister_reboot: |
706 | unregister_reboot_notifier(&usb_pcwd_notifier); | 706 | unregister_reboot_notifier(&usb_pcwd_notifier); |
707 | error: | 707 | error: |
708 | usb_pcwd_delete (usb_pcwd); | 708 | if (usb_pcwd) |
709 | usb_pcwd_delete(usb_pcwd); | ||
709 | usb_pcwd_device = NULL; | 710 | usb_pcwd_device = NULL; |
710 | return retval; | 711 | return retval; |
711 | } | 712 | } |