X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fwatchdog%2Fpcwd_usb.c;fp=drivers%2Fchar%2Fwatchdog%2Fpcwd_usb.c;h=2da5ac99687c60fba0660c713fc34370d6762c5c;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=1533f56baa42f8304e889b280994510c380cabec;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index 1533f56ba..2da5ac996 100644 --- a/drivers/char/watchdog/pcwd_usb.c +++ b/drivers/char/watchdog/pcwd_usb.c @@ -24,7 +24,6 @@ * http://www.berkprod.com/ or http://www.pcwatchdog.com/ */ -#include #include #include #include @@ -42,6 +41,8 @@ #include #include #include +#include +#include /* For HID_REQ_SET_REPORT & HID_DT_REPORT */ #ifdef CONFIG_USB_DEBUG @@ -109,10 +110,6 @@ MODULE_DEVICE_TABLE (usb, usb_pcwd_table); #define CMD_ENABLE_WATCHDOG 0x30 /* Enable / Disable Watchdog */ #define CMD_DISABLE_WATCHDOG CMD_ENABLE_WATCHDOG -/* Some defines that I like to be somewhere else like include/linux/usb_hid.h */ -#define HID_REQ_SET_REPORT 0x09 -#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02) - /* We can only use 1 card due to the /dev/watchdog restriction */ static int cards_found; @@ -143,7 +140,7 @@ struct usb_pcwd_private { static struct usb_pcwd_private *usb_pcwd_device; /* prevent races between open() and disconnect() */ -static DECLARE_MUTEX (disconnect_sem); +static DEFINE_MUTEX(disconnect_mutex); /* local function prototypes */ static int usb_pcwd_probe (struct usb_interface *interface, const struct usb_device_id *id); @@ -158,7 +155,7 @@ static struct usb_driver usb_pcwd_driver = { }; -static void usb_pcwd_intr_done(struct urb *urb, struct pt_regs *regs) +static void usb_pcwd_intr_done(struct urb *urb) { struct usb_pcwd_private *usb_pcwd = (struct usb_pcwd_private *)urb->context; unsigned char *data = usb_pcwd->intr_buffer; @@ -316,6 +313,19 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temp return 0; } +static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left) +{ + unsigned char msb, lsb; + + /* Read the time that's left before rebooting */ + /* Note: if the board is not yet armed then we will read 0xFFFF */ + usb_pcwd_send_command(usb_pcwd, CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb); + + *time_left = (msb << 8) + lsb; + + return 0; +} + /* * /dev/watchdog handling */ @@ -421,8 +431,18 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); + case WDIOC_GETTIMELEFT: + { + int time_left; + + if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left)) + return -EFAULT; + + return put_user(time_left, p); + } + default: - return -ENOIOCTLCMD; + return -ENOTTY; } } @@ -500,7 +520,7 @@ static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code, * Kernel Interfaces */ -static struct file_operations usb_pcwd_fops = { +static const struct file_operations usb_pcwd_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = usb_pcwd_write, @@ -515,7 +535,7 @@ static struct miscdevice usb_pcwd_miscdev = { .fops = &usb_pcwd_fops, }; -static struct file_operations usb_pcwd_temperature_fops = { +static const struct file_operations usb_pcwd_temperature_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = usb_pcwd_temperature_read, @@ -538,8 +558,7 @@ static struct notifier_block usb_pcwd_notifier = { */ static inline void usb_pcwd_delete (struct usb_pcwd_private *usb_pcwd) { - if (usb_pcwd->intr_urb != NULL) - usb_free_urb (usb_pcwd->intr_urb); + usb_free_urb(usb_pcwd->intr_urb); if (usb_pcwd->intr_buffer != NULL) usb_buffer_free(usb_pcwd->udev, usb_pcwd->intr_size, usb_pcwd->intr_buffer, usb_pcwd->intr_dma); @@ -612,7 +631,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8); /* set up the memory buffer's */ - if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, SLAB_ATOMIC, &usb_pcwd->intr_dma))) { + if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma))) { printk(KERN_ERR PFX "Out of memory\n"); goto error; } @@ -704,7 +723,8 @@ err_out_misc_deregister: err_out_unregister_reboot: unregister_reboot_notifier(&usb_pcwd_notifier); error: - usb_pcwd_delete (usb_pcwd); + if (usb_pcwd) + usb_pcwd_delete(usb_pcwd); usb_pcwd_device = NULL; return retval; } @@ -723,7 +743,7 @@ static void usb_pcwd_disconnect(struct usb_interface *interface) struct usb_pcwd_private *usb_pcwd; /* prevent races with open() */ - down (&disconnect_sem); + mutex_lock(&disconnect_mutex); usb_pcwd = usb_get_intfdata (interface); usb_set_intfdata (interface, NULL); @@ -749,7 +769,7 @@ static void usb_pcwd_disconnect(struct usb_interface *interface) cards_found--; - up (&disconnect_sem); + mutex_unlock(&disconnect_mutex); printk(KERN_INFO PFX "USB PC Watchdog disconnected\n"); }