2 * Copyright (C) 1993-1995 Bas Laarhoven. 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2, or (at your option) 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 14 You should have received a copy of the GNU General Public License 15 along with this program; see the file COPYING. If not, write to 16 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 * This file contains the code that interfaces the kernel 20 * for the QIC-40/80 floppy-tape driver for Linux. 23 #include <linux/module.h> 24 #include <linux/version.h> 25 #include <linux/errno.h> 27 #include <asm/segment.h> 28 #include <linux/kernel.h> 29 #include <linux/signal.h> 30 #include <linux/major.h> 31 #include <linux/malloc.h> 32 #include <linux/ftape.h> 36 #include"kernel-interface.h" 37 #include"ftape-read.h" 38 #include"ftape-write.h" 48 /* Allocating a 96Kb DMAable buffer in one chunk wont work due to 49 * memory fragmentation. To avoid this, it is broken up into 50 * NR_BUFFERS chunks of 32Kbyte. --khp 53 byte
*tape_buffer
[NR_BUFFERS
] = {NULL
}; 57 static int busy_flag
=0; 58 static int old_sigmask
; 60 static intftape_open(struct inode
*ino
,struct file
*filep
); 61 static voidftape_close(struct inode
*ino
,struct file
*filep
); 62 static intftape_ioctl(struct inode
*ino
,struct file
*filep
, 63 unsigned int command
,unsigned long arg
); 64 static intftape_read(struct inode
*ino
,struct file
*fp
,char*buff
, 66 static intftape_write(struct inode
*ino
,struct file
*fp
,const char*buff
, 69 static struct file_operations ftape_cdev
= 73 ftape_write
,/* write */ 76 ftape_ioctl
,/* ioctl */ 79 ftape_close
,/* release */ 84 * DMA'able memory allocation stuff. 87 /* Pure 2^n version of get_order */ 88 staticinlineint__get_order(unsigned long size
) 92 size
>>= (PAGE_SHIFT
-1); 102 void*dmaalloc(int order
) 104 return(void*)__get_dma_pages(GFP_KERNEL
, order
); 108 voiddmafree(void*addr
,int order
) 110 free_pages((unsigned long) addr
, order
); 114 * Called by modules package when installing the driver 115 * or by kernel during the initialization phase 119 #define ftape_init init_module 126 TRACE_FUN(5,"ftape_init"); 128 printk(KERN_INFO
"ftape-2.08 960314\n" 129 KERN_INFO
" (c) 1993-1995 Bas Laarhoven (bas@vimec.nl)\n" 130 KERN_INFO
" (c) 1995-1996 Kai Harrekilde-Petersen (khp@pip.dknet.dk)\n" 131 KERN_INFO
" QIC-117 driver for QIC-40/80/3010/3020 tape drives\n" 132 KERN_INFO
" Compiled for kernel version %s" 134 " with versioned symbols" 136 "\n", kernel_version
); 138 /* print a short no-nonsense boot message */ 139 printk("ftape-2.08 960314 for Linux 1.3.70\n"); 141 TRACE(3,"installing QIC-117 ftape driver..."); 142 if(register_chrdev(QIC117_TAPE_MAJOR
,"ft", &ftape_cdev
)) { 143 TRACE(1,"register_chrdev failed"); 147 TRACEx1(3,"ftape_init @ 0x%p", ftape_init
); 149 * Allocate the DMA buffers. They are deallocated at cleanup() time. 151 order
=__get_order(BUFF_SIZE
); 152 for(n
=0; n
< NR_BUFFERS
; n
++) { 153 tape_buffer
[n
] = (byte
*)dmaalloc(order
); 154 if(!tape_buffer
[n
]) { 155 TRACE(1,"dmaalloc() failed"); 156 for(n
=0; n
< NR_BUFFERS
; n
++) { 158 dmafree(tape_buffer
[n
], order
); 159 tape_buffer
[n
] = NULL
; 162 current
->blocked
= old_sigmask
;/* restore mask */ 163 if(unregister_chrdev(QIC117_TAPE_MAJOR
,"ft") !=0) { 164 TRACE(3,"unregister_chrdev failed"); 169 TRACEx2(3,"dma-buffer #%d @ %p", n
, tape_buffer
[n
]); 174 ftape_failure
=1;/* inhibit any operation but open */ 175 udelay_calibrate();/* must be before fdc_wait_calibrate ! */ 176 fdc_wait_calibrate(); 179 register_symtab(0);/* remove global ftape symbols */ 186 /* Called by modules package when removing the driver 188 voidcleanup_module(void) 192 TRACE_FUN(5,"cleanup_module"); 194 if(unregister_chrdev(QIC117_TAPE_MAJOR
,"ft") !=0) { 197 TRACE(3,"successful"); 199 order
=__get_order(BUFF_SIZE
); 200 for(n
=0; n
< NR_BUFFERS
; n
++) { 202 dmafree(tape_buffer
[n
], order
); 203 tape_buffer
[n
] = NULL
; 204 TRACEx1(3,"removed dma-buffer #%d", n
); 206 TRACEx1(1,"dma-buffer #%d == NULL (bug?)", n
); 215 static intftape_open(struct inode
*ino
,struct file
*filep
) 217 TRACE_FUN(4,"ftape_open"); 219 MOD_INC_USE_COUNT
;/* lock module in memory */ 221 TRACEi(5,"called for minor",MINOR(ino
->i_rdev
)); 223 TRACE(1,"failed: already busy"); 224 MOD_DEC_USE_COUNT
;/* unlock module in memory */ 228 if((MINOR(ino
->i_rdev
) & ~FTAPE_NO_REWIND
) >3) { 229 TRACE(1,"failed: illegal unit nr"); 230 MOD_DEC_USE_COUNT
;/* unlock module in memory */ 234 if(ftape_unit
== -1|| FTAPE_UNIT
!= (MINOR(ino
->i_rdev
) &3)) { 235 /* Other selection than last time 239 ftape_unit
=MINOR(ino
->i_rdev
); 240 ftape_failure
=0;/* allow tape operations */ 241 old_sigmask
= current
->blocked
; 242 current
->blocked
= _BLOCK_ALL
; 243 fdc_save_drive_specs();/* save Drive Specification regs on i82078-1's */ 244 result
=_ftape_open(); 246 TRACE(1,"_ftape_open failed"); 247 current
->blocked
= old_sigmask
;/* restore mask */ 248 MOD_DEC_USE_COUNT
;/* unlock module in memory */ 253 /* Mask signals that will disturb proper operation of the 254 * program that is calling. 256 current
->blocked
= old_sigmask
| _DO_BLOCK
; 262 /* Close ftape device 264 static voidftape_close(struct inode
*ino
,struct file
*filep
) 266 TRACE_FUN(4,"ftape_close"); 269 if(!busy_flag
||MINOR(ino
->i_rdev
) != ftape_unit
) { 270 TRACE(1,"failed: not busy or wrong unit"); 272 return;/* keep busy_flag !(?) */ 274 current
->blocked
= _BLOCK_ALL
; 275 result
=_ftape_close(); 277 TRACE(1,"_ftape_close failed"); 279 fdc_restore_drive_specs();/* restore original values */ 280 ftape_failure
=1;/* inhibit any operation but open */ 282 current
->blocked
= old_sigmask
;/* restore before open state */ 284 MOD_DEC_USE_COUNT
;/* unlock module in memory */ 287 /* Ioctl for ftape device 289 static intftape_ioctl(struct inode
*ino
,struct file
*filep
, 290 unsigned int command
,unsigned long arg
) 292 TRACE_FUN(4,"ftape_ioctl"); 296 if(!busy_flag
||MINOR(ino
->i_rdev
) != ftape_unit
|| ftape_failure
) { 297 TRACE(1,"failed: not busy, failure or wrong unit"); 301 old_sigmask
= current
->blocked
;/* save mask */ 302 current
->blocked
= _BLOCK_ALL
; 303 /* This will work as long as sizeof( void*) == sizeof( long) 305 result
=_ftape_ioctl(command
, (void*) arg
); 306 current
->blocked
= old_sigmask
;/* restore mask */ 311 /* Read from tape device 313 static intftape_read(struct inode
*ino
,struct file
*fp
,char*buff
,int req_len
) 315 TRACE_FUN(5,"ftape_read"); 319 TRACEi(5,"called with count:", req_len
); 320 if(!busy_flag
||MINOR(ino
->i_rdev
) != ftape_unit
|| ftape_failure
) { 321 TRACE(1,"failed: not busy, failure or wrong unit"); 325 old_sigmask
= current
->blocked
;/* save mask */ 326 current
->blocked
= _BLOCK_ALL
; 327 result
=_ftape_read(buff
, req_len
); 328 TRACEi(7,"return with count:", result
); 329 current
->blocked
= old_sigmask
;/* restore mask */ 334 /* Write to tape device 336 static intftape_write(struct inode
*ino
,struct file
*fp
,const char*buff
,int req_len
) 338 TRACE_FUN(8,"ftape_write"); 342 TRACEi(5,"called with count:", req_len
); 343 if(!busy_flag
||MINOR(ino
->i_rdev
) != ftape_unit
|| ftape_failure
) { 344 TRACE(1,"failed: not busy, failure or wrong unit"); 348 old_sigmask
= current
->blocked
;/* save mask */ 349 current
->blocked
= _BLOCK_ALL
; 350 result
=_ftape_write(buff
, req_len
); 351 TRACEi(7,"return with count:", result
); 352 current
->blocked
= old_sigmask
;/* restore mask */