Date: Wed, 12 Feb 97 11:35:02 JST From: Shunsuke Akiyama <akiyama@kme.mei.co.jp> To: FreeBSD-gnats-submit@freebsd.org Subject: kern/2716: od.c/sd.c non 512 byte/sector support improvements. Message-ID: <9702120235.AA15035@kmegate.kme.mei.co.jp> Resent-Message-ID: <199702120250.SAA12974@freefall.freebsd.org>
index | next in thread | raw e-mail
>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 <akiyama@kme.mei.co.jp>.
+ * 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:
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9702120235.AA15035>
