*** 0.2.1.17 1993/03/08 18:51:59 --- kernel/chr_drv/tpqic02.c 1993/03/22 17:41:28 *************** *** 1,6 **** ! /* $Id: tpqic02.c,v 0.2.1.17 1993/03/08 18:51:59 root Exp $ * ! * Driver for tape drive support for Linux-i386 0.99.6. * * Copyright (c) 1992 by H. H. Bergman. All rights reserved. * Current e-mail address: s0356514@let.rug.nl --- 1,6 ---- ! /* $Id: tpqic02.c,v 0.2.1.18 1993/03/22 17:39:47 root Exp root $ * ! * Driver for tape drive support for Linux-i386 0.99.7. * * Copyright (c) 1992 by H. H. Bergman. All rights reserved. * Current e-mail address: s0356514@let.rug.nl *************** *** 27,32 **** --- 27,35 ---- * You are not allowed to change this line nor the text above. * * $Log: tpqic02.c,v $ + * Revision 0.2.1.18 1993/03/22 17:39:47 root + * Moved to 0.99.7. Added Archive MTSEEK and MTTELL support. + * * Revision 0.2.1.17 1993/03/08 18:51:59 root * Tried to `fix' write-once bug in previous release. * *************** *** 164,170 **** /* check existence of required configuration parameters */ #if !defined(TAPE_QIC02_MAJOR) || !defined(TAPE_QIC02_PORT) || \ !defined(TAPE_QIC02_IRQ) || !defined(TAPE_QIC02_DMA) ! #error "tape_qic02 configuration error: check config*.h" #endif --- 167,173 ---- /* check existence of required configuration parameters */ #if !defined(TAPE_QIC02_MAJOR) || !defined(TAPE_QIC02_PORT) || \ !defined(TAPE_QIC02_IRQ) || !defined(TAPE_QIC02_DMA) ! #error tape_qic02 configuration error #endif *************** *** 182,189 **** static volatile struct tpstatus tperror; /* last drive status */ ! static char rcs_revision[] = "$Revision: 0.2.1.17 $"; ! static char rcs_date[] = "$Date: 1993/03/08 18:51:59 $"; /* Flag bits for status and outstanding requests. * (Could all be put in one bit-field-struct.) --- 185,192 ---- static volatile struct tpstatus tperror; /* last drive status */ ! static char rcs_revision[] = "$Revision: 0.2.1.18 $"; ! static char rcs_date[] = "$Date: 1993/03/22 17:39:47 $"; /* Flag bits for status and outstanding requests. * (Could all be put in one bit-field-struct.) *************** *** 233,238 **** --- 236,246 ---- static flag reported_write_eof = NO; + #ifdef TP_HAVE_SEEK + /* This is for doing `mt seek ' */ + static char seek_addr_buf[SEEK_BUF_SIZE]; + #endif + /* In write mode, we have to write a File Mark after the last block written, * when the tape device is closed. Tape repositioning and reading in write *************** *** 310,316 **** "Reset occured" /* 13 */}, {~TP_WRP, TP_ST0|TP_FIL|TP_MBD, /* NOTE: ST1 not set! */ "Marginal block detected" /* 14 */}, ! {~(TP_ST0|TP_WRP|TP_EOM|TP_UDA|TP_BNL|TP_FIL), TP_ST1|TP_EOR, "End of recorded media" /* extra: 15 */}, /* 15 is returned when SEEKEOD completes successfully */ {~(TP_WRP|TP_ST0), TP_ST1|TP_BOM, --- 318,325 ---- "Reset occured" /* 13 */}, {~TP_WRP, TP_ST0|TP_FIL|TP_MBD, /* NOTE: ST1 not set! */ "Marginal block detected" /* 14 */}, ! {~(TP_ST0|TP_WRP|TP_EOM|TP_UDA|TP_BNL|TP_FIL |TP_NDT), TP_ST1|TP_EOR, ! /********** Is the extra TP_NDT really needed Eddy? **********/ "End of recorded media" /* extra: 15 */}, /* 15 is returned when SEEKEOD completes successfully */ {~(TP_WRP|TP_ST0), TP_ST1|TP_BOM, *************** *** 557,566 **** * This routine is also used by rdstatus(), so in that case, any exception * must be ignored (`ignore_ex' flag). */ ! static int notify_cmd(short ignore_ex) { int i; /* wait 1 usec before asserting /REQUEST */ udelay(1); --- 566,577 ---- * This routine is also used by rdstatus(), so in that case, any exception * must be ignored (`ignore_ex' flag). */ ! static int notify_cmd(char cmd, short ignore_ex) { int i; + outb_p(cmd, QIC_CMD_PORT); /* output the command */ + /* wait 1 usec before asserting /REQUEST */ udelay(1); *************** *** 647,655 **** /* not ready and no exception && timeout not expired yet */ while (((stat = inb_p(QIC_STAT_PORT) & QIC_STAT_MASK) == QIC_STAT_MASK) && (jiffiestimeout = jiffies + 30; /* nap 0.30 sec between checks */ current->state = TASK_INTERRUPTIBLE; ! schedule(); /* but could be woken up earlier by signals... */ } /* don't use jiffies for this test because it may have changed by now */ --- 658,666 ---- /* not ready and no exception && timeout not expired yet */ while (((stat = inb_p(QIC_STAT_PORT) & QIC_STAT_MASK) == QIC_STAT_MASK) && (jiffiestimeout = jiffies + 30; /* nap 0.30 sec between checks, */ current->state = TASK_INTERRUPTIBLE; ! schedule(); /* but could be woken up earlier by signals... */ } /* don't use jiffies for this test because it may have changed by now */ *************** *** 667,672 **** --- 678,702 ---- } /* wait_for_ready */ + /* Send some data to the drive */ + static int send_qic02_data(char sb[], unsigned size, int ignore_ex) + { + int i, stat; + + for (i=0; ii_rdev; unsigned short flags = filp->f_flags; unsigned long bytes_todo, bytes_done, total_bytes_done = 0; *************** *** 1762,1767 **** --- 1809,1821 ---- return -EACCES; + /* Make sure buffer is safe to write into. */ + error = verify_area(VERIFY_WRITE, buf, count); + if (error) { + printk(TPQIC_NAME ": read: verify_area(WRITE, %lx, %x) failed\n", buf, count); + return error; + } + /* This is rather ugly because it has to implement a finite state * machine in order to handle the EOF situations properly. */ *************** *** 1788,1798 **** /* Application program has already received EOF * (above), now continue with next file on tape, * if possible. ! * Assume that upon reaching the FM, EXCEPTION is ! * set, causing a sense(), and skipping the FM. ! ***** exact behaviour is not clear to me. */ ! /*********** this should check for (EOD|NDT), not EOM, 'cause we can read past EW: ************/ if (status_eom_detected) /* If EOM, nothing left to read, so keep returning EOFs. *** should probably set some flag to avoid clearing --- 1842,1852 ---- /* Application program has already received EOF * (above), now continue with next file on tape, * if possible. ! * When the FM is reached, EXCEPTION is set, ! * causing a sense(). Subsequent read/writes will ! * continue after the FM. */ ! /*********** ?????????? this should check for (EOD|NDT), not EOM, 'cause we can read past EW: ************/ if (status_eom_detected) /* If EOM, nothing left to read, so keep returning EOFs. *** should probably set some flag to avoid clearing *************** *** 1815,1821 **** if (bytes_todo>0) { /* start reading data */ - verify_area(buf, bytes_todo); /* check buffer is valid */ if (is_exception()) /****************************************/ tpqputs("is_exception() before start_dma()!"); /****************************************************************** --- 1869,1874 ---- *************** *** 1905,1910 **** --- 1958,1964 ---- */ static int tape_qic02_write(struct inode * inode, struct file * filp, char * buf, int count) { + int error; dev_t dev = inode->i_rdev; unsigned short flags = filp->f_flags; unsigned long bytes_todo, bytes_done, total_bytes_done = 0; *************** *** 1928,1933 **** --- 1982,1994 ---- return -EACCES; /* don't even try when write protected */ } + /* Make sure buffer is safe to read from. */ + error = verify_area(VERIFY_READ, buf, count); + if (error) { + printk(TPQIC_NAME ": write: verify_area(READ, %lx, %x) failed\n", buf, count); + return error; + } + if (doing_read == YES) /************************** ?????????????? ***********/ terminate_read(0); *************** *** 2033,2038 **** --- 2094,2101 ---- unsigned short dens; int s; + status_open = NO; + if (TP_DIAGS(dev)) { printk("tape_qic02_open: dev=%x, flags=%x ", dev, flags); } *************** *** 2067,2076 **** case O_RDWR: /* reads are allowed as long as nothing is written */ mode_access = WRITE; break; ! default: ! return -EINVAL; } /* not allowed to do QCMD_DENS_* unless tape is rewound */ if ((TP_DENS(dev)!=0) && (TP_DENS(current_tape_dev) != TP_DENS(dev))) { /* force rewind if minor bits have changed, --- 2130,2146 ---- case O_RDWR: /* reads are allowed as long as nothing is written */ mode_access = WRITE; break; ! } ! ! ! /* This is to avoid tape-changed problems (TP_CNI exception). */ ! if (is_exception()) { ! s = tp_sense(TP_WRP|TP_EOM|TP_BOM|TP_CNI|TP_EOR); ! if (s != TE_OK) ! return -EIO; } + /* not allowed to do QCMD_DENS_* unless tape is rewound */ if ((TP_DENS(dev)!=0) && (TP_DENS(current_tape_dev) != TP_DENS(dev))) { /* force rewind if minor bits have changed, *************** *** 2184,2194 **** */ terminate_write(-1); ! if (status_dead==YES) { tpqputs("device dead on close!?"); - status_open = NO; - return; - } if (status_open==NO) { tpqputs("in release(): device not open"); --- 2254,2261 ---- */ terminate_write(-1); ! if (status_dead==YES) tpqputs("device dead on close!?"); if (status_open==NO) { tpqputs("in release(): device not open"); *************** *** 2212,2217 **** --- 2279,2285 ---- static int tape_qic02_ioctl(struct inode * inode, struct file * filp, unsigned int iocmd, unsigned int ioarg) { + int error; short i; int dev_maj = MAJOR(inode->i_rdev); int c; *************** *** 2218,2223 **** --- 2286,2296 ---- struct mtop operation; char *stp, *argp; + #ifdef TP_HAVE_TELL + unsigned char blk_addr[6]; + struct mtpos ioctl_tell; + #endif + if (TP_DIAGS(current_tape_dev)) printk(TPQIC_NAME ": ioctl(%4x, %4x, %4x)\n", dev_maj, iocmd, ioarg); *************** *** 2242,2247 **** --- 2315,2323 ---- tpqputs("sizeof(struct mtop) does not match!"); return -EFAULT; } + error = verify_area(VERIFY_READ, (char *) ioarg, sizeof(operation)); + if (error) + return error; /* copy mtop struct from user space to kernel space */ stp = (char *) &operation; *************** *** 2262,2273 **** if (operation.mt_count < 0) tpqputs("Warning: negative mt_count ignored"); ioctl_status.mt_resid = operation.mt_count; ! while (operation.mt_count > 0) { ! operation.mt_count--; ! if ((c = do_ioctl_cmd(operation.mt_op)) != 0) ! return c; ! ioctl_status.mt_resid = operation.mt_count; } return 0; --- 2338,2362 ---- if (operation.mt_count < 0) tpqputs("Warning: negative mt_count ignored"); + ioctl_status.mt_resid = operation.mt_count; ! if (operation.mt_op == MTSEEK) { ! seek_addr_buf[0] = (operation.mt_count>>16)&0xff; ! seek_addr_buf[1] = (operation.mt_count>>8)&0xff; ! seek_addr_buf[2] = (operation.mt_count)&0xff; ! if (operation.mt_count>>24) ! return -EINVAL; ! ! if ((error = do_ioctl_cmd(operation.mt_op)) != 0) ! return error; ! ioctl_status.mt_resid = 0; ! } else { ! while (operation.mt_count > 0) { ! operation.mt_count--; ! if ((error = do_ioctl_cmd(operation.mt_op)) != 0) ! return error; ! ioctl_status.mt_resid = operation.mt_count; ! } } return 0; *************** *** 2281,2288 **** return -EFAULT; } ! /* check for valid address */ ! verify_area((void *) ioarg, sizeof(ioctl_status)); /* It appears (gmt(1)) that it is normal behaviour to * first set the status with MTNOP, and then to read --- 2370,2379 ---- return -EFAULT; } ! /* check for valid user address */ ! error = verify_area(VERIFY_WRITE, (void *) ioarg, sizeof(ioctl_status)); ! if (error) ! return error; /* It appears (gmt(1)) that it is normal behaviour to * first set the status with MTNOP, and then to read *************** *** 2295,2300 **** --- 2386,2425 ---- for (i=0; i> IOCSIZE_SHIFT) != sizeof(struct mtpos)) { + tpqputs("sizeof(struct mtpos) does not match!"); + return -EFAULT; + } + + /* check for valid user address */ + error = verify_area(VERIFY_WRITE, (void *) ioarg, sizeof(ioctl_tell)); + if (error) + return error; + + tpqputs("MTTELL reading block address"); + if ((doing_read==YES) || (doing_write==YES)) + finish_rw(QCMDV_TELL_BLK); + + c = rdstatus(blk_addr, sizeof(blk_addr), QCMDV_TELL_BLK); + if (c!=TE_OK) + return -EIO; + + ioctl_tell.mt_blkno = (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5]; + + /* copy results to user space */ + stp = (char *) &ioctl_tell; + argp = (char *) ioarg; + for (i=0; i=0x10000)) ! panic(TPQIC_NAME ": internal error: DMA buffer size out of range\n"); printk(TPQIC_NAME ": DMA buffers: %u blocks", NR_BLK_BUF); --- 2488,2513 ---- *******/ /* get IRQ */ if (irqaction(TAPE_QIC02_IRQ, &tape_qic02_sigaction)) { ! printk(TPQIC_NAME ": can't allocate IRQ%d for QIC-02 tape\n", TAPE_QIC02_IRQ); ! return kmem_start; } /* After IRQ, allocate DMA channel */ if (request_dma(TAPE_QIC02_DMA)) { ! printk(TPQIC_NAME ": can't allocate DMA%d for QIC-02 tape\n", ! TAPE_QIC02_DMA); ! return kmem_start; } ! if (TPSTATSIZE != 6) { ! printk(TPQIC_NAME ": internal error: tpstatus struct incorrect!\n"); ! return kmem_start; ! } ! if ((TPQBUF_SIZE<512) || (TPQBUF_SIZE>=0x10000)) { ! printk(TPQIC_NAME ": internal error: DMA buffer size out of range\n"); ! return kmem_start; ! } printk(TPQIC_NAME ": DMA buffers: %u blocks", NR_BLK_BUF); *************** *** 2390,2401 **** buffaddr = align_buffer((unsigned long) &tape_qic02_buf, TAPE_BLKSIZE); printk(", at address 0x%lx (0x%lx)\n", buffaddr, (unsigned long) &tape_qic02_buf); ! if (buffaddr+TPQBUF_SIZE>=0x100000) ! #if 0 ! panic(TPQIC_NAME ": DMA buffer *must* be in lower 1MB\n"); ! #else ! tpqputs("Buffer not in lower 1MB"); #endif /* prepare timer */ TIMEROFF; --- 2518,2535 ---- buffaddr = align_buffer((unsigned long) &tape_qic02_buf, TAPE_BLKSIZE); printk(", at address 0x%lx (0x%lx)\n", buffaddr, (unsigned long) &tape_qic02_buf); ! #ifndef CONFIG_MAX_16M ! if (buffaddr+TPQBUF_SIZE>=0x1000000) { ! printk(TPQIC_NAME ": DMA buffer *must* be in lower 16MB\n"); ! return kmem_start; ! } #endif + + /* If we got this far, install driver functions */ + if (register_chrdev(TAPE_QIC02_MAJOR, TPQIC_NAME, &tape_qic02_fops)) { + printk(TPQIC_NAME ": Unable to get chrdev major %d\n", TAPE_QIC02_MAJOR); + return kmem_start; + } /* prepare timer */ TIMEROFF; *** 0.14 1993/03/08 18:51:59 --- include/linux/tpqic02.h 1993/03/22 17:42:35 *************** *** 1,4 **** ! /* $Id: tpqic02.h,v 0.14 1993/03/08 18:51:59 root Exp $ * * Include file for QIC-02 driver for Linux. * --- 1,4 ---- ! /* $Id: tpqic02.h,v 0.15 1993/03/22 17:39:47 root Exp root $ * * Include file for QIC-02 driver for Linux. * *************** *** 21,26 **** --- 21,28 ---- /* make TAPE_QIC02_IFC expand to something */ #define WANGTEK 1 /* don't know about Wangtek QIC-36 */ #define EVEREX WANGTEK /* I heard *some* of these are identical */ + #define EVEREX_811V EVEREX /* With TEAC MT 2ST 45D */ + #define EVEREX_831V EVEREX #define ARCHIVE 3 #define ARCHIVE_SC400 ARCHIVE /* rumoured to be from the pre-SMD-age */ #define ARCHIVE_SC402 ARCHIVE /* don't know much about SC400 */ *************** *** 50,56 **** * number. This must be avoided. Check for timer.h conflicts too. */ ! #define TAPE_QIC02_DRIVE MT_ISWT5150 /* drive type */ #define TAPE_QIC02_IFC WANGTEK /* interface card type */ /* #define TAPE_QIC02_IFC ARCHIVE */ #define TAPE_QIC02_MAJOR 12 /* major device number. /dev/loop seems to use 12 as well :-( */ --- 52,59 ---- * number. This must be avoided. Check for timer.h conflicts too. */ ! #define TAPE_QIC02_DRIVE MT_ISQIC02_ALL_FEATURES /* drive type */ ! /* #define TAPE_QIC02_DRIVE MT_ISWT5150 */ #define TAPE_QIC02_IFC WANGTEK /* interface card type */ /* #define TAPE_QIC02_IFC ARCHIVE */ #define TAPE_QIC02_MAJOR 12 /* major device number. /dev/loop seems to use 12 as well :-( */ *************** *** 75,80 **** --- 78,102 ---- #define TP_HAVE_RAS1 #define TP_HAVE_RAS2 + #elif TAPE_QIC02_DRIVE == MT_ISARCHIVESC499 /* Archive SC-499 QIC-36 controller */ + #define TP_HAVE_DENS /* can do set density (QIC-11 / QIC-24) */ + #define TP_HAVE_FSR /* can skip one block forwards */ + #define TP_HAVE_BSR /* can skip one block backwards */ + #define TP_HAVE_EOD /* can seek to end of recorded data */ + #define TP_HAVE_RAS1 /* can run selftest 1 */ + #define TP_HAVE_RAS2 /* can run selftest 2 */ + /* These last two selftests shouldn't be used yet! */ + + #elif TAPE_QIC02_DRIVE == MT_ISARCHIVE_2150L + #define TP_HAVE_DENS /* can do set density (QIC-24 / QIC-120 / QIC-150) */ + #define TP_HAVE_FSR /* can skip one block forwards */ + #define TP_HAVE_BSR /* can skip one block backwards */ + #define TP_HAVE_EOD /* can seek to end of recorded data */ + #define TP_HAVE_TELL /* can read current block address */ + #define TP_HAVE_SEEK /* can seek to block */ + #define TP_HAVE_RAS1 /* can run selftest 1 */ + #define TP_HAVE_RAS2 /* can run selftest 2 */ + /* These last two selftests shouldn't be used yet! */ #elif TAPE_QIC02_DRIVE == MT_ISQIC02_ALL_FEATURES #define TP_HAVE_DENS /* can do set density */ *************** *** 82,91 **** --- 104,116 ---- #define TP_HAVE_FSR /* can skip one block forwards */ #define TP_HAVE_BSR /* can skip one block backwards */ #define TP_HAVE_EOD /* can seek to end of recorded data */ + #define TP_HAVE_SEEK /* seek to block address */ + #define TP_HAVE_TELL /* tell current block address */ #define TP_HAVE_RAS1 /* can run selftest 1 */ #define TP_HAVE_RAS2 /* can run selftest 2 */ /* These last two selftests shouldn't be used yet! */ + #else #error No QIC-02 tape drive type defined! /* If your drive is not listed above, first try the 'ALL_FEATURES', *************** *** 209,214 **** --- 234,249 ---- #define QCMD_SELF_TST1 0xC2 /* run self test 1 (nondestructive) */ #define QCMD_SELF_TST2 0xCA /* run self test 2 (destructive) */ + + + /* "Vendor Unique" codes */ + #if defined(MT_ISARCHIVESC499) || defined(MT_ISARCHIVE_2150L) + # define QCMDV_TELL_BLK 0xAE /* read current block address */ + # define QCMDV_SEEK_BLK 0xAD /* seek to specific block */ + # define SEEK_BUF_SIZE 3 /* address is 3 bytes */ + #endif + + /* Optional, QFA (Quick File Access) commands. * Not all drives support this, but those that do could use these commands * to implement semi-non-sequential access. `mt fsf` would benefit from this. *************** *** 226,231 **** --- 261,268 ---- #define QFA_RD_POS 0xCF /* read position+status bytes */ #define QFA_SEEK_EOD 0xA1 /* seek EOD within current partition */ #define QFA_SEEK_BLK 0xAF /* seek to a block within current partition */ + + /* Minor device codes for tapes: * |7|6|5|4|3|2|1|0| *** 1.4 1993/03/01 00:16:41 --- include/linux/aperf.h 1993/03/22 17:43:14 *************** *** 1,4 **** ! /* $Id: aperf.h,v 1.4 1993/03/01 00:16:41 root Exp $ * * Written by Hennus Bergman and Linus Torvalds. */ --- 1,4 ---- ! /* $Id: aperf.h,v 1.5 1993/03/22 17:39:47 root Exp root $ * * Written by Hennus Bergman and Linus Torvalds. */ *************** *** 10,26 **** #define USEC_PER_HZ (1000000/HZ) /* nr of usec per 1/HZ second */ #define TENPICO_PER_HZ 1000000000L /* nr of 10psec per 1/HZ second */ - #define SUB_PER_CYCLE 32 /* More than 0, less than, say 100. */ ! /* Argument must be an int. */ /********* NOTE: THERE MAY BE PROBLEMS ON VERY SLOW MACHINES -- VERIFY ON 386SX-16,8 to ********* make sure it works!!!!! *********/ #ifdef REALLY_SLOW_CPU /* e.g. something slower than a 386DX perhaps */ # define DELAY_LOOP(count) __asm__ __volatile__("\n1:\tdecl %0;jns 1b" \ :"=r" (count):"0" (count)); #else # define DELAY_LOOP(count,steps) DELAY_LOOP2(count, steps) # define DELAY_LOOP2(count,steps) \ __asm__ __volatile__("\n1:\tsubl $" #steps ",%0;jns 1b" \ --- 10,29 ---- #define USEC_PER_HZ (1000000/HZ) /* nr of usec per 1/HZ second */ #define TENPICO_PER_HZ 1000000000L /* nr of 10psec per 1/HZ second */ ! /* Argument for DELAY_LOOP() must be a signed int. */ /********* NOTE: THERE MAY BE PROBLEMS ON VERY SLOW MACHINES -- VERIFY ON 386SX-16,8 to ********* make sure it works!!!!! *********/ #ifdef REALLY_SLOW_CPU /* e.g. something slower than a 386DX perhaps */ + + # define SUB_PER_CYCLE 1 # define DELAY_LOOP(count) __asm__ __volatile__("\n1:\tdecl %0;jns 1b" \ :"=r" (count):"0" (count)); #else + + # define SUB_PER_CYCLE 32 /* More than 0, less than, say 100. */ # define DELAY_LOOP(count,steps) DELAY_LOOP2(count, steps) # define DELAY_LOOP2(count,steps) \ __asm__ __volatile__("\n1:\tsubl $" #steps ",%0;jns 1b" \ *************** *** 48,54 **** } ! extern void cpu_speed_test(); #endif /* _LINUX_APERF_H */ --- 51,57 ---- } ! extern void cpu_speed_test(void); #endif /* _LINUX_APERF_H */ *** 1.4 1993/03/01 00:19:42 --- kernel/aperf.c 1993/03/22 17:43:39 *************** *** 1,4 **** ! /* $Id: aperf.c,v 1.4 1993/03/01 00:19:42 root Exp $ * * Various things needed for the Linux Performance Index (TM). * Written by Hennus Bergman. --- 1,4 ---- ! /* $Id: aperf.c,v 1.5 1993/03/22 17:39:47 root Exp root $ * * Various things needed for the Linux Performance Index (TM). * Written by Hennus Bergman. *************** *** 14,22 **** #include /* This is where the speed results are stored. */ ! unsigned int usec_loop_iter_count = 20*SUB_PER_CYCLE; /* per usec */ ! unsigned int speed_result_count_udelay = 20*SUB_PER_CYCLE*USEC_PER_HZ; /* per HZ */ #if CONFIG_MEASURE_CPU_SPEED --- 14,26 ---- #include /* This is where the speed results are stored. + * Default values are intended to be comfortable for i486 + * up to something like 100MHz. (Untested. ;-) + * + * My i486DX/33MHz produces 8.31*SUB_PER_CYCLE. */ ! unsigned int usec_loop_iter_count = 30*SUB_PER_CYCLE; /* per usec */ ! unsigned int speed_result_count_udelay = 30*SUB_PER_CYCLE*USEC_PER_HZ; /* per HZ */ #if CONFIG_MEASURE_CPU_SPEED *************** *** 72,78 **** speed_counter = 0; udelay(INITIAL_TICKS); } while (speed_counter