2 * USB HID boot protocol mouse support based on MS BusMouse driver, psaux 3 * driver, and Linus's skeleton USB mouse driver. Fixed up a lot by Linus. 7 * version 0.30? Paul Ashton 1999/08/19 - Fixed behaviour on mouse 8 * disconnect and suspend/resume. Added module parameter "force=1" 9 * to allow opening of the mouse driver before mouse has been plugged 10 * in (enables consistent XF86Config settings). Fixed module use count. 11 * Documented missing blocking/non-blocking read handling (not fixed). 13 * version 0.20: Linus rewrote read_mouse() to do PS/2 and do it 14 * correctly. Events are added together, not queued, to keep the rodent sober. 16 * version 0.02: Hmm, the mouse seems drunk because I'm queueing the events. 17 * This is wrong: when an application (like X or gpm) reads the mouse device, 18 * it wants to find out the mouse's current position, not its recent history. 19 * The button thing turned out to be UHCI not flipping data toggle, so half the 20 * packets were thrown out. 22 * version 0.01: Switched over to busmouse protocol, and changed the minor 23 * number to 32 (same as uusbd's hidbp driver). Buttons work more sanely now, 24 * but it still doesn't generate button events unless you move the mouse. 26 * version 0.0: Driver emulates a PS/2 mouse, stealing /dev/psaux (sorry, I 27 * know that's not very nice). Moving in the X and Y axes works. Buttons don't 28 * work right yet: X sees a lot of MotionNotify/ButtonPress/ButtonRelease 29 * combos when you hold down a button and drag the mouse around. Probably has 30 * some additional bugs on an SMP machine. 33 #include <linux/kernel.h> 34 #include <linux/sched.h> 35 #include <linux/signal.h> 36 #include <linux/errno.h> 37 #include <linux/miscdevice.h> 38 #include <linux/random.h> 39 #include <linux/poll.h> 40 #include <linux/init.h> 41 #include <linux/malloc.h> 42 #include <linux/module.h> 43 #include <linux/spinlock.h> 47 #define USB_MOUSE_MINOR 32 50 unsigned char buttons
;/* current button state */ 51 long dx
;/* dx, dy, dz are change since last read */ 54 int present
;/* this mouse is plugged in */ 55 int active
;/* someone is has this mouse's device open */ 56 int ready
;/* the mouse has changed state since the last read */ 57 int suspended
;/* mouse disconnected */ 58 wait_queue_head_t wait
;/* for polling */ 59 struct fasync_struct
*fasync
; 60 /* later, add a list here to support multiple mice */ 61 /* but we will also need a list of file pointers to identify it */ 63 /* FIXME: move these to a per-mouse structure */ 64 struct usb_device
*dev
;/* host controller this mouse is on */ 65 void* irq_handle
;/* host controller's IRQ transfer handle */ 66 __u8 bEndpointAddress
;/* these are from the endpoint descriptor */ 67 __u8 bInterval
;/* ... used when calling usb_request_irq */ 70 static struct mouse_state static_mouse_state
; 72 spinlock_t usb_mouse_lock
= SPIN_LOCK_UNLOCKED
; 74 static int force
=0;/* allow the USB mouse to be opened even if not there (yet) */ 75 MODULE_PARM(force
,"i"); 77 static intmouse_irq(int state
,void*__buffer
,int len
,void*dev_id
) 79 signed char*data
= __buffer
; 80 /* finding the mouse is easy when there's only one */ 81 struct mouse_state
*mouse
= &static_mouse_state
; 84 printk(KERN_DEBUG
"%s(%d):state %d, bp %p, len %d, dp %p\n", 85 __FILE__
, __LINE__
, state
, __buffer
, len
, dev_id
); 88 * USB_ST_NOERROR is the normal case. 89 * USB_ST_REMOVED occurs if mouse disconnected or suspend/resume 90 * USB_ST_INTERNALERROR occurs if system suspended then mouse removed 91 * followed by resume. On UHCI could then occur every second 92 * In both cases, suspend the mouse 93 * On other states, ignore 97 case USB_ST_INTERNALERROR
: 98 printk(KERN_DEBUG
"%s(%d): Suspending\n", 101 return0;/* disable */ 102 case USB_ST_NOERROR
:break; 103 default:return1;/* ignore */ 106 /* if a mouse moves with no one listening, do we care? no */ 110 /* if the USB mouse sends an interrupt, then something noteworthy 111 must have happened */ 112 mouse
->buttons
= data
[0] &0x07; 113 mouse
->dx
+= data
[1];/* data[] is signed, so this works */ 114 mouse
->dy
-= data
[2];/* y-axis is reversed */ 115 mouse
->dz
-= data
[3]; 118 add_mouse_randomness((mouse
->buttons
<<24) + (mouse
->dz
<<16) + 119 (mouse
->dy
<<8) + mouse
->dx
); 121 wake_up_interruptible(&mouse
->wait
); 123 kill_fasync(mouse
->fasync
, SIGIO
); 128 static intfasync_mouse(int fd
,struct file
*filp
,int on
) 131 struct mouse_state
*mouse
= &static_mouse_state
; 133 retval
=fasync_helper(fd
, filp
, on
, &mouse
->fasync
); 139 static intrelease_mouse(struct inode
* inode
,struct file
* file
) 141 struct mouse_state
*mouse
= &static_mouse_state
; 143 fasync_mouse(-1, file
,0); 145 printk(KERN_DEBUG
"%s(%d): MOD_DEC\n", __FILE__
, __LINE__
); 148 if(--mouse
->active
==0) { 150 /* stop polling the mouse while its not in use */ 151 usb_release_irq(mouse
->dev
, mouse
->irq_handle
); 152 /* never keep a reference to a released IRQ! */ 153 mouse
->irq_handle
= NULL
; 159 static intopen_mouse(struct inode
* inode
,struct file
* file
) 161 struct mouse_state
*mouse
= &static_mouse_state
; 163 printk(KERN_DEBUG
"%s(%d): open_mouse\n", __FILE__
, __LINE__
); 165 * First open may fail since mouse_probe() may get called after this 166 * if module load is in response to the open 167 * mouse_probe() sets mouse->present. This open can be delayed by 168 * specifying force=1 in module load 169 * This helps if you want to insert the USB mouse after starting X 173 if(force
)/* always load the driver even if no mouse (yet) */ 175 printk(KERN_DEBUG
"%s(%d): forced open\n", 183 /* prevent the driver from being unloaded while its in use */ 184 printk(KERN_DEBUG
"%s(%d): MOD_INC\n", __FILE__
, __LINE__
); 185 /* Increment use count even if already active */ 191 mouse
->buttons
= mouse
->dx
= mouse
->dy
= mouse
->dz
=0; 193 if(!mouse
->present
)/* only get here if force == 1 */ 196 /* start the usb controller's polling of the mouse */ 197 mouse
->irq_handle
=usb_request_irq(mouse
->dev
,usb_rcvctrlpipe(mouse
->dev
, mouse
->bEndpointAddress
), mouse_irq
, mouse
->bInterval
, NULL
); 202 static ssize_t
write_mouse(struct file
* file
, 203 const char* buffer
,size_t count
, loff_t
*ppos
) 209 * Look like a PS/2 mouse, please.. 211 * The PS/2 protocol is fairly strange, but 212 * oh, well, it's at least common.. 214 static ssize_t
read_mouse(struct file
* file
,char* buffer
,size_t count
, loff_t
*ppos
) 218 struct mouse_state
*mouse
= &static_mouse_state
; 221 * FIXME - Other mouse drivers handle blocking and nonblocking reads 222 * differently here... 227 case0: {/* buttons and sign */ 228 int buttons
= mouse
->buttons
; 234 put_user(buttons
, buffer
); 244 put_user(dx
, buffer
); 254 put_user(dy
, buffer
); 265 * The only way to get here is to do a read() of 266 * more than 3 bytes: if you read a byte at a time 267 * you will just ever see states 0-2, for backwards 270 * So you can think of this as a packet interface, 271 * where you have arbitrary-sized packets, and you 272 * only ever see the first three bytes when you read 273 * them in small chunks. 275 {/* fallthrough - dz */ 278 put_user(dz
, buffer
); 289 static unsigned intmouse_poll(struct file
*file
, poll_table
* wait
) 291 struct mouse_state
*mouse
= &static_mouse_state
; 293 poll_wait(file
, &mouse
->wait
, wait
); 295 return POLLIN
| POLLRDNORM
; 299 struct file_operations usb_mouse_fops
= { 300 NULL
,/* mouse_seek */ 303 NULL
,/* mouse_readdir */ 304 mouse_poll
,/* mouse_poll */ 305 NULL
,/* mouse_ioctl */ 306 NULL
,/* mouse_mmap */ 314 static struct miscdevice usb_mouse
= { 315 USB_MOUSE_MINOR
,"USB mouse", &usb_mouse_fops
318 static intmouse_probe(struct usb_device
*dev
) 320 struct usb_interface_descriptor
*interface
; 321 struct usb_endpoint_descriptor
*endpoint
; 322 struct mouse_state
*mouse
= &static_mouse_state
; 324 /* We don't handle multi-config mice */ 325 if(dev
->descriptor
.bNumConfigurations
!=1) 328 /* We don't handle multi-interface mice */ 329 if(dev
->config
[0].bNumInterfaces
!=1) 332 /* Is it a mouse interface? */ 333 interface
= &dev
->config
[0].interface
[0].altsetting
[0]; 334 if(interface
->bInterfaceClass
!=3) 336 if(interface
->bInterfaceSubClass
!=1) 338 if(interface
->bInterfaceProtocol
!=2) 341 /* Multiple endpoints? What kind of mutant ninja-mouse is this? */ 342 if(interface
->bNumEndpoints
!=1) 345 endpoint
= &interface
->endpoint
[0]; 347 /* Output endpoint? Curiousier and curiousier.. */ 348 if(!(endpoint
->bEndpointAddress
&0x80)) 351 /* If it's not an interrupt endpoint, we'd better punt! */ 352 if((endpoint
->bmAttributes
&3) !=3) 355 printk("USB mouse found\n"); 357 if(usb_set_configuration(dev
, dev
->config
[0].bConfigurationValue
)) { 358 printk(KERN_INFO
" Failed usb_set_configuration: mouse\n"); 362 /* these are used to request the irq when the mouse is opened */ 364 mouse
->bEndpointAddress
= endpoint
->bEndpointAddress
; 365 mouse
->bInterval
= endpoint
->bInterval
; 369 /* This appears to let USB mouse survive disconnection and */ 370 /* APM suspend/resume */ 373 printk(KERN_DEBUG
"%s(%d): mouse resume\n", __FILE__
, __LINE__
); 374 /* restart the usb controller's polling of the mouse */ 375 mouse
->irq_handle
=usb_request_irq(mouse
->dev
, 376 usb_rcvctrlpipe(mouse
->dev
, mouse
->bEndpointAddress
), 377 mouse_irq
, mouse
->bInterval
, NULL
); 384 static voidmouse_disconnect(struct usb_device
*dev
) 386 struct mouse_state
*mouse
= &static_mouse_state
; 388 /* stop the usb interrupt transfer */ 390 usb_release_irq(mouse
->dev
, mouse
->irq_handle
); 391 /* never keep a reference to a released IRQ! */ 394 mouse
->irq_handle
= NULL
; 396 /* this might need work */ 398 printk("Mouse disconnected\n"); 401 static struct usb_driver mouse_driver
= { 408 intusb_mouse_init(void) 410 struct mouse_state
*mouse
= &static_mouse_state
; 412 mouse
->present
= mouse
->active
= mouse
->suspended
=0; 413 mouse
->irq_handle
= NULL
; 414 init_waitqueue_head(&mouse
->wait
); 415 mouse
->fasync
= NULL
; 417 misc_register(&usb_mouse
); 419 usb_register(&mouse_driver
); 420 printk(KERN_INFO
"USB HID boot protocol mouse driver registered.\n"); 424 voidusb_mouse_cleanup(void) 426 struct mouse_state
*mouse
= &static_mouse_state
; 428 /* stop the usb interrupt transfer */ 430 usb_release_irq(mouse
->dev
, mouse
->irq_handle
); 431 /* never keep a reference to a released IRQ! */ 432 mouse
->irq_handle
= NULL
; 435 /* this, too, probably needs work */ 436 usb_deregister(&mouse_driver
); 437 misc_deregister(&usb_mouse
); 443 returnusb_mouse_init(); 446 voidcleanup_module(void)