1 #include <linux/init.h> 
   2 #include <linux/module.h> 
   4 #include <linux/types.h> 
   6 #include <asm/uaccess.h> 
   7 #include <linux/poll.h> 
   8 #include <linux/sched.h> 
   9 #include <linux/interrupt.h> 
  10 #include <asm/delay.h> 
  12 static const char *version 
= "$Id: dhwk.c,v 1.1 2007-03-10 22:35:54 sithglan Exp $"; 
  13 static unsigned long ioaddr
; 
  14 static unsigned long locks
; 
  16 #define BUFFER_SIZE 32768 
  18 static unsigned char send_buffer
[BUFFER_SIZE
]; 
  19 static unsigned char recv_buffer
[BUFFER_SIZE
]; 
  21 static wait_queue_head_t send_wq
; 
  22 static wait_queue_head_t receive_wq
; 
  23 static u8 irq
; /* FIXME: Get it from the pci struct */ 
  24 static int my_dhwk_dev_id
; 
  26 MODULE_LICENSE("Dual BSD/GPL"); 
  28 #define MODULE_NAME "dhwk" 
  31 #define INTERRUPTS_PLEASE 1 
  33 #define SDR (ioaddr + 0) 
  34 #define RDR (ioaddr + 2) 
  35 #define ISR (ioaddr + 4) 
  36 #define CTR (ioaddr + 6) 
  39 dhwk_open(struct inode 
*inode
, struct file 
*f
) 
  41         if (iminor(inode
) != 0) { 
  47         if (( (f
->f_flags 
& O_ACCMODE
) == O_RDONLY
 
  48            || (f
->f_flags 
& O_ACCMODE
) == O_RDWR
) 
  50                 if (f
->f_flags 
& O_NONBLOCK
) { 
  59         if (( (f
->f_flags 
& O_ACCMODE
) == O_WRONLY
 
  60            || (f
->f_flags 
& O_ACCMODE
) == O_RDWR
) 
  62                 if (f
->f_flags 
& O_NONBLOCK
) { 
  71         if (( (f
->f_flags 
& O_ACCMODE
) == O_RDONLY
 
  72            || (f
->f_flags 
& O_ACCMODE
) == O_RDWR
)) { 
  73                 test_and_set_bit(0, &locks
); 
  76         if (( (f
->f_flags 
& O_ACCMODE
) == O_WRONLY
 
  77            || (f
->f_flags 
& O_ACCMODE
) == O_RDWR
)) { 
  78                 test_and_set_bit(1, &locks
); 
  85 dhwk_release(struct inode 
*i
, struct file 
*f
) 
  88         if (( (f
->f_flags 
& O_ACCMODE
) == O_RDONLY
 
  89            || (f
->f_flags 
& O_ACCMODE
) == O_RDWR
)) { 
  93         if (( (f
->f_flags 
& O_ACCMODE
) == O_WRONLY
 
  94            || (f
->f_flags 
& O_ACCMODE
) == O_RDWR
)) { 
 102 dhwk_read(struct file 
*f
, char __user 
*u
, size_t size
, loff_t 
*offset
) 
 109         if (! access_ok(VERIFY_WRITE
, u
, size
)) { 
 113         while (count 
< size
) { 
 117                 if (next_status 
== 0) { 
 119                         if (! (status 
& 0x0200)) { 
 120                                 /* Receive FIFO Empty */ 
 121                                 if (f
->f_flags 
& O_NONBLOCK
) { 
 122                                         __copy_to_user(u 
+ count 
- (count 
% BUFFER_SIZE
), 
 123                                                 recv_buffer
, count 
% BUFFER_SIZE 
+ 1); 
 127 #if INTERRUPTS_PLEASE 
 128                                         wait_event_interruptible(receive_wq
, inw(ISR
) & 0x0200); 
 129                                         if (signal_pending(current
)) { 
 135                                         goto dhwk_read_again
; 
 138                         } else if (! (status 
& 0x0400)) { 
 139                                 /* Receive FIFO Half Full */ 
 150                 if ((word 
& 0xFF) != 0xc3) { 
 151                         short debug_enable 
= inw(ioaddr 
+ 8); 
 152                         printk(KERN_ALERT 
"dhwk: Fehler: 0x%08x\n", 0x00 | word
); 
 156                 recv_buffer
[count 
% BUFFER_SIZE
] = (unsigned char) word
; 
 158                 if (count 
% BUFFER_SIZE 
== (BUFFER_SIZE 
- 1) 
 159                 || count 
== (size 
- 1)) { 
 160                         __copy_to_user(u 
+ count 
- (count 
% BUFFER_SIZE
), 
 161                                 recv_buffer
, count 
% BUFFER_SIZE 
+ 1); 
 171 dhwk_write(struct file 
*f
, const char __user 
*u
, size_t size
, loff_t 
*offset
) 
 178         if (! access_ok(VERIFY_READ
, u
, size
)) { 
 182         while (count 
< size
) { 
 183                 if (grabbed 
<= count
) { 
 184                         __copy_from_user(send_buffer
, u 
+ count
, 
 185                                 (size 
- count
) < BUFFER_SIZE 
? (size 
- count
) : BUFFER_SIZE
); 
 186                         grabbed 
+= (size 
- count
) < BUFFER_SIZE 
? (size 
- count
) : BUFFER_SIZE
; 
 191                 if (next_status 
== 0) { 
 193                         if (! (status 
& 0x8000)) { 
 195                                 if (f
->f_flags 
& O_NONBLOCK
) { 
 199 #if INTERRUPTS_PLEASE 
 200                                         wait_event_interruptible(send_wq
, inw(ISR
) & 0x0800); 
 201                                         if (signal_pending(current
)) { 
 207                                         goto dhwk_write_again
; 
 210                         } else if (status 
& 0x4000) { 
 211                                 /* Send FIFO not HALF Full */ 
 218                 outw(0x0000 | send_buffer
[count 
% BUFFER_SIZE
], SDR
); 
 226 dhwk_poll(struct file 
*f
, struct poll_table_struct 
*pts
) 
 235         if (( (f
->f_flags 
& O_ACCMODE
) == O_RDONLY
 
 236            || (f
->f_flags 
& O_ACCMODE
) == O_RDWR
)) { 
 237                 if (f
->f_flags 
& O_NONBLOCK
) { 
 239                                 mask 
|= POLLIN 
| POLLRDNORM
; 
 247                         goto dhwk_poll_again
; 
 251         if (( (f
->f_flags 
& O_ACCMODE
) == O_WRONLY
 
 252            || (f
->f_flags 
& O_ACCMODE
) == O_RDWR
)) { 
 253                 if ((f
->f_flags 
& O_NONBLOCK
)) { 
 254                         /* If write is possible */ 
 255                         if (! (reg 
& 0x8000)) { 
 256                                 mask 
|= POLLOUT 
| POLLWRNORM
; 
 264                         goto dhwk_poll_again
; 
 273 dhwk_pci_init(struct pci_dev 
*pdev
, const struct pci_device_id 
*ent
) 
 277         printk(KERN_ALERT 
"dhwk: Gruppe 2: %s\n", version
); 
 279         ret 
= pci_enable_device(pdev
); 
 281                 printk(KERN_ERR 
"dhwk: Could not enable pci device.\n"); 
 282                 pci_disable_device(pdev
); 
 286         ret 
= pci_request_regions(pdev
, MODULE_NAME
); 
 288                 printk(KERN_ERR 
"dhwk: Could not request regions.\n"); 
 289                 pci_disable_device(pdev
); 
 295         ioaddr 
= pci_resource_start(pdev
, 0); 
 296         printk(KERN_ALERT 
"dhwk: ioaddr at 0x%08x irq 0x%02x\n", (unsigned int) ioaddr
, irq
); 
 298         /* Pull Reset (twice) */ 
 304         /* CLEAR WRONG STATUS */ 
 308         /* Enable Sender and Receiver and all available Interrupts */ 
 309         while ((inw(CTR
) & 0x06FF) != 0x06FF) { 
 315 static void __devexit
 
 316 dhwk_pci_exit(struct pci_dev 
*pdev
) 
 320         ret 
= inw(ISR
); /* Get pending interrupts down */ 
 322         pci_release_regions(pdev
); 
 323         pci_disable_device(pdev
); 
 324         pci_set_drvdata(pdev
, NULL
); 
 325         printk(KERN_ALERT 
"dhwk: Gruppe 2: Module unloaded.\n"); 
 328 static struct pci_device_id dhwk_pci_tbl
[] = { 
 329         {0x2222, 0xaffe, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, /* FIXME */ 
 331         {0xbaff, 0xaffe, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, /* FIXME */ 
 336 static struct pci_driver dhwk_pci_driver 
= { 
 338         .id_table       
= dhwk_pci_tbl
, 
 339         .probe          
= dhwk_pci_init
, 
 340         .remove         
= dhwk_pci_exit
, 
 343 struct file_operations dhwk_fops 
= { 
 344         .owner 
= THIS_MODULE
, 
 349         .release 
= dhwk_release
, 
 353 interrupt_handler(int irq_to_check
, void *dev_id
, struct pt_regs 
*regs
) 
 355         register unsigned short status
; 
 358         if (status 
& 0x0200) { 
 359                 wake_up_interruptible(& receive_wq
); 
 362         if (status 
& 0x8000) { 
 363                 wake_up_interruptible(& send_wq
); 
 366         if (irq_to_check 
== irq
) {  
 379         ret 
= pci_module_init(& dhwk_pci_driver
); 
 384         ret 
= register_chrdev(DHWK_MAJOR
, MODULE_NAME
, & dhwk_fops
); 
 386                 printk (KERN_ALERT 
"dhwk: unable to get major %d\n", DHWK_MAJOR
); 
 387                 pci_unregister_driver(& dhwk_pci_driver
); 
 391         init_waitqueue_head(& send_wq
); 
 392         init_waitqueue_head(& receive_wq
); 
 394 #if INTERRUPTS_PLEASE 
 396         ret 
= request_irq(irq
, interrupt_handler
, SA_INTERRUPT
, "dhwk", &my_dhwk_dev_id
); 
 398         ret 
= request_irq(irq
, interrupt_handler
, SA_SHIRQ
, "dhwk", &my_dhwk_dev_id
); 
 400                 printk (KERN_ALERT 
"dhwk: unable to register interrupt %d\n", irq
); 
 401                 pci_unregister_driver(& dhwk_pci_driver
); 
 402                 unregister_chrdev(DHWK_MAJOR
, MODULE_NAME
); 
 413         free_irq(irq
, &my_dhwk_dev_id
); 
 414         pci_unregister_driver(& dhwk_pci_driver
); 
 415         unregister_chrdev(DHWK_MAJOR
, MODULE_NAME
); 
 418 module_init(dhwk_init
); 
 419 module_exit(dhwk_exit
);