Skip site navigation (1)Skip section navigation (2)
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>

next in thread | raw e-mail | index | archive | help

>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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9702120235.AA15035>