From owner-freebsd-bugs Tue Feb 11 18:50:14 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id SAA12991 for bugs-outgoing; Tue, 11 Feb 1997 18:50:14 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id SAA12974; Tue, 11 Feb 1997 18:50:08 -0800 (PST) Resent-Date: Tue, 11 Feb 1997 18:50:08 -0800 (PST) Resent-Message-Id: <199702120250.SAA12974@freefall.freebsd.org> Resent-From: gnats (GNATS Management) Resent-To: freebsd-bugs Resent-Reply-To: FreeBSD-gnats@freefall.FreeBSD.org, akiyama@kme.mei.co.jp Received: from who.cdrom.com (who.cdrom.com [204.216.27.3]) by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id SAA12884 for ; Tue, 11 Feb 1997 18:49:56 -0800 (PST) Received: from vcgate3.mei.co.jp (vcgate3.mei.co.jp [202.32.14.53]) by who.cdrom.com (8.7.5/8.6.11) with ESMTP id SAA03362 for ; Tue, 11 Feb 1997 18:36:41 -0800 (PST) Received: by vcgate3.mei.co.jp (8.7.5+2.6Wbeta7/5.9:4.9:vcgate0:961204) id LAA19230; Wed, 12 Feb 1997 11:34:50 +0900 (JST) Received: by vcmei.vanc.mei.co.jp (5.65mei1.1/5.9:4.9:vcmei:970206) id AA17459; Wed, 12 Feb 97 11:35:45 +0900 Received: by kmegate.kme.mei.co.jp (4.1/5.5:4.6:kmegate:970203) id AA15035; Wed, 12 Feb 97 11:35:02 JST Message-Id: <9702120235.AA15035@kmegate.kme.mei.co.jp> Date: Wed, 12 Feb 97 11:35:02 JST From: Shunsuke Akiyama Reply-To: akiyama@kme.mei.co.jp To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: kern/2716: od.c/sd.c non 512 byte/sector support improvements. Sender: owner-bugs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >Number: 2716 >Category: kern >Synopsis: od.c/sd.c non 512 byte/sector support improvements. >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue Feb 11 18:50:05 PST 1997 >Last-Modified: >Originator: Shunsuke Akiyama >Organization: Kyushu Matsushita Electric Co., Ltd. >Release: FreeBSD 3.0-970124-SNAP i386 >Environment: FreeBSD 3.0-970124-SNAP / od / sd >Description: Currently sys/scsi/{od,sd}.c supports 1024/2048 byte/sector media. But it used too much multiply and division operations. I changed it to use arithmetic shift operations. It's works fine for sd and od device with my environment since couple of weeks age. >How-To-Repeat: N/A >Fix: =================================================================== --- sys/scsi/od.c 1997/02/10 02:18:50 1.27 +++ sys/scsi/od.c 1997/02/11 13:28:30 1.27.1.1 @@ -1,5 +1,6 @@ /* - * Copyright (c) 1995,1996 Shunsuke Akiyama. All rights reserved. + * Copyright (c) 1995,1996,1997 Shunsuke Akiyama . + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -52,6 +53,7 @@ * WARNING! Use at your own risk. Joerg's ancient SONY SMO drive * groks it fine, while Shunsuke's Fujitsu chokes on it and times * out. + * #define OD_AUTO_TURNOFF */ @@ -111,9 +113,10 @@ u_int32_t disksize; /* total number sectors */ u_int16_t rpm; /* medium rotation rate */ } params; + int kbtodb; /* kernel to driver block shift */ struct diskslices *dk_slices; /* virtual drives */ struct buf_queue_head buf_queue; - int dkunit; /* disk stats unit number */ + int dkunit; /* disk stats unit number */ #ifdef DEVFS /* Eventually move all these to common disk struct. */ void *b_devfs_token; @@ -360,8 +363,13 @@ } switch (od->params.secsiz) { case SECSIZE : + od->kbtodb = 0; + break; case 1024 : + od->kbtodb = 1; + break; case 2048 : + od->kbtodb = 2; break; default : printf("od%ld: Can't deal with %d bytes logical blocks\n", @@ -446,7 +454,7 @@ u_int32_t opri; struct scsi_data *od; u_int32_t unit; - int secsize; + int scale; odstrats++; unit = ODUNIT((bp->b_dev)); @@ -463,24 +471,23 @@ /* * Odd number of bytes or negative offset */ - if (bp->b_blkno < 0 ) { + if (bp->b_blkno < 0) { bp->b_error = EINVAL; printf("od_strategy: Negative block number: 0x%x\n", bp->b_blkno); goto bad; } - - secsize = od->params.secsiz; + scale = od->kbtodb; /* make sure the blkno is scalable */ - if( (bp->b_blkno % (secsize/DEV_BSIZE)) != 0 ) { + if ((bp->b_blkno & ((1 << scale) - 1)) != 0) { bp->b_error = EINVAL; printf("od_strategy: Block number is not multiple of sector size (2): 0x%x\n", bp->b_blkno); goto bad; } /* make sure that the transfer size is a multiple of the sector size */ - if( (bp->b_bcount % secsize) != 0 ) { + if ((bp->b_bcount & (od->params.secsiz - 1)) != 0) { bp->b_error = EINVAL; printf("od_strategy: Invalid b_bcount %d at block number: 0x%x\n", bp->b_bcount, bp->b_blkno); goto bad; @@ -490,30 +497,26 @@ * Do bounds checking, adjust transfer, and set b_pblkno. */ { - int status; - int sec_blk_ratio = secsize/DEV_BSIZE; - /* save original block number and size */ - int b_blkno = bp->b_blkno; - int b_bcount = bp->b_bcount; - - /* replace with scaled values */ - bp->b_blkno /= sec_blk_ratio; - bp->b_bcount /= sec_blk_ratio; + int status; + /* save original block number and size */ + daddr_t b_blkno = bp->b_blkno; + long b_bcount = bp->b_bcount; + + /* replace with scaled values */ + bp->b_blkno >>= scale; + bp->b_bcount >>= scale; - /* have dscheck enforce limits and map to physical block number */ - status = dscheck(bp, od->dk_slices); + /* have dscheck enforce limits and map to physical block number */ + status = dscheck(bp, od->dk_slices); - /* restore original values to prevent bad side effects in block system */ - bp->b_blkno = b_blkno; - bp->b_bcount = b_bcount; - /* scale resid */ - bp->b_resid *= sec_blk_ratio; - - /* see if the mapping failed */ - if (status <= 0) - { - goto done; /* XXX check b_resid */ - } + /* restore original values to prevent bad side effects in block system */ + bp->b_blkno = b_blkno; + bp->b_bcount = b_bcount; + bp->b_resid <<= scale; /* scale resid */ + + /* see if the mapping failed */ + if (status <= 0) + goto done; /* XXX check b_resid */ } opri = SPLOD(); @@ -585,7 +588,6 @@ struct buf *bp = 0; struct scsi_rw_big cmd; u_int32_t blkno, nblk; - u_int32_t secsize; SC_DEBUG(sc_link, SDEV_DB2, ("odstart ")); /* @@ -622,13 +624,12 @@ * We have a buf, now we know we are going to go through * With this thing.. */ - secsize = od->params.secsiz; blkno = bp->b_pblkno; - if (bp->b_bcount & (secsize - 1)) + if (bp->b_bcount & (od->params.secsiz - 1)) { goto bad; } - nblk = bp->b_bcount / secsize; + nblk = bp->b_bcount >> (DEV_BSHIFT + od->kbtodb); /* * Fill out the scsi command =================================================================== --- sys/scsi/sd.c 1997/02/10 02:18:54 1.101 +++ sys/scsi/sd.c 1997/02/11 13:34:55 1.101.1.2 @@ -1,4 +1,3 @@ - /* * Written by Julian Elischer (julian@dialix.oz.au) * for TRW Financial Systems for use under the MACH(2.5) operating system. @@ -82,15 +81,16 @@ u_int32_t flags; #define SDINIT 0x04 /* device has been init'd */ struct disk_parms { - u_char heads; /* Number of heads */ - u_int16_t cyls; /* Number of cylinders */ + u_char heads; /* Number of heads */ + u_int16_t cyls; /* Number of cylinders */ u_char sectors; /*dubious *//* Number of sectors/track */ u_int16_t secsiz; /* Number of bytes/sector */ u_int32_t disksize; /* total number sectors */ } params; + int kbtodb; /* kernel to driver block shift */ struct diskslices *dk_slices; /* virtual drives */ struct buf_queue_head buf_queue; - int dkunit; /* disk stats unit number */ + int dkunit; /* disk stats unit number */ #ifdef DEVFS void *b_devfs_token; void *c_devfs_token; @@ -326,8 +326,13 @@ goto bad; switch (sd->params.secsiz) { case SECSIZE: /* 512 */ + sd->kbtodb = 0; + break; case 1024: + sd->kbtodb = 1; + break; case 2048: + sd->kbtodb = 2; break; default: printf("sd%ld: Can't deal with %d bytes logical blocks\n", @@ -406,7 +411,8 @@ { u_int32_t opri; struct scsi_data *sd; - u_int32_t unit, secsize; + u_int32_t unit; + int scale; sdstrats++; unit = SDUNIT((bp->b_dev)); @@ -441,23 +447,23 @@ /* * Odd number of bytes or negative offset */ - if (bp->b_blkno < 0 ) { + if (bp->b_blkno < 0) { bp->b_error = EINVAL; printf("sd_strategy: Negative block number: 0x%x\n", bp->b_blkno); goto bad; } - secsize = sd->params.secsiz; + scale = sd->kbtodb; /* make sure the blkno is scalable */ - if( (bp->b_blkno % (secsize/DEV_BSIZE)) != 0 ) { + if ((bp->b_blkno & ((1 << scale) - 1)) != 0) { bp->b_error = EINVAL; printf("sd_strategy: Block number is not multiple of sector size (2): 0x%x\n", bp->b_blkno); goto bad; } /* make sure that the transfer size is a multiple of the sector size */ - if( (bp->b_bcount % secsize) != 0 ) { + if ((bp->b_bcount & (sd->params.secsiz - 1)) != 0) { bp->b_error = EINVAL; printf("sd_strategy: Invalid b_bcount %d at block number: 0x%x\n", bp->b_bcount, bp->b_blkno); goto bad; @@ -468,28 +474,25 @@ */ { int status; - int sec_blk_ratio = secsize/DEV_BSIZE; /* save original block number and size */ - int b_blkno = bp->b_blkno; - int b_bcount = bp->b_bcount; + daddr_t b_blkno = bp->b_blkno; + long b_bcount = bp->b_bcount; /* replace with scaled values */ - bp->b_blkno /= sec_blk_ratio; - bp->b_bcount /= sec_blk_ratio; - + bp->b_blkno >>= scale; + bp->b_bcount >>= scale; + /* enforce limits and map to physical block number */ status = dscheck(bp, sd->dk_slices); /* prevent bad side effects in block system */ bp->b_blkno = b_blkno; bp->b_bcount = b_bcount; - - /* scale resid */ - bp->b_resid *= sec_blk_ratio; + bp->b_resid <<= scale; /* scale resid */ /* see if the mapping failed */ if (status <= 0) - goto done; /* XXX check b_resid */ + goto done; /* XXX check b_resid */ } #endif opri = SPLSD(); @@ -563,7 +566,7 @@ register struct scsi_data *sd = sc_link->sd; struct buf *bp = NULL; struct scsi_rw_big cmd; - u_int32_t blkno, nblk, secsize; + u_int32_t blkno, nblk; SC_DEBUG(sc_link, SDEV_DB2, ("sdstart ")); /* @@ -600,13 +603,12 @@ * We have a buf, now we know we are going to go through * With this thing.. */ - secsize = sd->params.secsiz; blkno = bp->b_pblkno; - if (bp->b_bcount & (secsize - 1)) + if (bp->b_bcount & (sd->params.secsiz - 1)) { goto bad; } - nblk = bp->b_bcount / secsize; + nblk = bp->b_bcount >> (DEV_BSHIFT + sd->kbtodb); /* * Fill out the scsi command >Audit-Trail: >Unformatted: