X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fwatchdog%2Fpcwd_usb.c;h=2da5ac99687c60fba0660c713fc34370d6762c5c;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=d88228eb5b366ad0f07248e1fb4400881107b13a;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index d88228eb5..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 @@ -56,7 +57,8 @@ /* Module and Version Information */ -#define DRIVER_VERSION "v1.00 (28/02/2004)" +#define DRIVER_VERSION "1.01" +#define DRIVER_DATE "15 Mar 2005" #define DRIVER_AUTHOR "Wim Van Sebroeck " #define DRIVER_DESC "Berkshire USB-PC Watchdog driver" #define DRIVER_LICENSE "GPL" @@ -78,12 +80,7 @@ static int heartbeat = WATCHDOG_HEARTBEAT; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0context; unsigned char *data = usb_pcwd->intr_buffer; @@ -226,7 +218,7 @@ static int usb_pcwd_send_command(struct usb_pcwd_private *usb_pcwd, unsigned cha if (usb_control_msg(usb_pcwd->udev, usb_sndctrlpipe(usb_pcwd->udev, 0), HID_REQ_SET_REPORT, HID_DT_REPORT, 0x0200, usb_pcwd->interface_number, buf, sizeof(buf), - HZ) != sizeof(buf)) { + USB_COMMAND_TIMEOUT) != sizeof(buf)) { dbg("usb_pcwd_send_command: error in usb_control_msg for cmd 0x%x 0x%x 0x%x\n", cmd, *msb, *lsb); } /* wait till the usb card processed the command, @@ -321,17 +313,26 @@ 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 */ -static ssize_t usb_pcwd_write(struct file *file, const char *data, +static ssize_t usb_pcwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { - /* Can't seek (pwrite) on this device */ - if (ppos != &file->f_pos) - return -ESPIPE; - /* See if we got the magic character 'V' and reload the timer */ if (len) { if (!nowayout) { @@ -360,6 +361,8 @@ static ssize_t usb_pcwd_write(struct file *file, const char *data, static int usb_pcwd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + void __user *argp = (void __user *)arg; + int __user *p = argp; static struct watchdog_info ident = { .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | @@ -370,12 +373,12 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, switch (cmd) { case WDIOC_GETSUPPORT: - return copy_to_user((struct watchdog_info *) arg, &ident, + return copy_to_user(argp, &ident, sizeof (ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, (int *) arg); + return put_user(0, p); case WDIOC_GETTEMP: { @@ -384,7 +387,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature)) return -EFAULT; - return put_user(temperature, (int *) arg); + return put_user(temperature, p); } case WDIOC_KEEPALIVE: @@ -395,7 +398,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, { int new_options, retval = -EINVAL; - if (get_user (new_options, (int *) arg)) + if (get_user (new_options, p)) return -EFAULT; if (new_options & WDIOS_DISABLECARD) { @@ -415,7 +418,7 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, { int new_heartbeat; - if (get_user(new_heartbeat, (int *) arg)) + if (get_user(new_heartbeat, p)) return -EFAULT; if (usb_pcwd_set_heartbeat(usb_pcwd_device, new_heartbeat)) @@ -426,10 +429,20 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, } case WDIOC_GETTIMEOUT: - return put_user(heartbeat, (int *)arg); + 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; } } @@ -442,7 +455,7 @@ static int usb_pcwd_open(struct inode *inode, struct file *file) /* Activate */ usb_pcwd_start(usb_pcwd_device); usb_pcwd_keepalive(usb_pcwd_device); - return 0; + return nonseekable_open(inode, file); } static int usb_pcwd_release(struct inode *inode, struct file *file) @@ -456,8 +469,8 @@ static int usb_pcwd_release(struct inode *inode, struct file *file) printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); usb_pcwd_keepalive(usb_pcwd_device); } - clear_bit(0, &is_active); expect_release = 0; + clear_bit(0, &is_active); return 0; } @@ -465,19 +478,15 @@ static int usb_pcwd_release(struct inode *inode, struct file *file) * /dev/temperature handling */ -static ssize_t usb_pcwd_temperature_read(struct file *file, char *data, +static ssize_t usb_pcwd_temperature_read(struct file *file, char __user *data, size_t len, loff_t *ppos) { int temperature; - /* Can't seek (pwrite) on this device */ - if (ppos != &file->f_pos) - return -ESPIPE; - if (usb_pcwd_get_temperature(usb_pcwd_device, &temperature)) return -EFAULT; - if (copy_to_user (data, &temperature, 1)) + if (copy_to_user(data, &temperature, 1)) return -EFAULT; return 1; @@ -485,7 +494,7 @@ static ssize_t usb_pcwd_temperature_read(struct file *file, char *data, static int usb_pcwd_temperature_open(struct inode *inode, struct file *file) { - return 0; + return nonseekable_open(inode, file); } static int usb_pcwd_temperature_release(struct inode *inode, struct file *file) @@ -511,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, @@ -526,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, @@ -549,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); @@ -576,12 +584,6 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi char fw_ver_str[20]; unsigned char option_switches, dummy; - /* See if the device offered us matches what we can accept */ - if ((udev->descriptor.idVendor != USB_PCWD_VENDOR_ID) || - (udev->descriptor.idProduct != USB_PCWD_PRODUCT_ID)) { - return -ENODEV; - } - cards_found++; if (cards_found > 1) { printk(KERN_ERR PFX "This driver only supports 1 device\n"); @@ -626,10 +628,10 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi usb_pcwd->udev = udev; usb_pcwd->interface = interface; usb_pcwd->interface_number = iface_desc->desc.bInterfaceNumber; - usb_pcwd->intr_size = (endpoint->wMaxPacketSize > 8 ? endpoint->wMaxPacketSize : 8); + 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; } @@ -681,15 +683,12 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi ((option_switches & 0x08) ? "ON" : "OFF")); /* Check that the heartbeat value is within it's range ; if not reset to the default */ - if (heartbeat < 1 || heartbeat > 0xFFFF) { - heartbeat = WATCHDOG_HEARTBEAT; + if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) { + usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT); printk(KERN_INFO PFX "heartbeat value must be 0exists = 0; /* Deregister */ - misc_deregister(&usb_pcwd_temperature_miscdev); misc_deregister(&usb_pcwd_miscdev); + misc_deregister(&usb_pcwd_temperature_miscdev); unregister_reboot_notifier(&usb_pcwd_notifier); up (&usb_pcwd->sem); @@ -769,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"); } @@ -791,7 +791,7 @@ static int __init usb_pcwd_init(void) return result; } - printk(KERN_INFO PFX DRIVER_DESC " " DRIVER_VERSION "\n"); + printk(KERN_INFO PFX DRIVER_DESC " v" DRIVER_VERSION " (" DRIVER_DATE ")\n"); return 0; }