Subject: port-sparc/2903: sparc fd.c patch to recognize NEC (Japanese) format.
To: None <gnats-bugs@gnats.netbsd.org>
From: MINOURA Makoto <minoura@kawasaki.flab.fujitsu.co.jp>
List: netbsd-bugs
Date: 10/29/1996 17:25:43
>Number:         2903
>Category:       port-sparc
>Synopsis:       sparc fd.c patch to recognize NEC (Japanese) format.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 29 00:35:01 1996
>Last-Modified:
>Originator:     MINOURA Makoto
>Organization:
MINOURA, Makoto <minoura@kawasaki.flab.fujitsu.co.jp>
Integrated Networks Laboratory, Fujitsu Labs. Ltd., JAPAN
=`We need NO American naval & military bases in Japan!!'=
>Release:        1.2
>Environment:
System: NetBSD ecology 1.2 NetBSD 1.2 (ECOLOGY) #0: Tue Oct 22 11:39:10 JST 1996 minoura@ecology:/usr/src/sys/arch/sparc/compile/ECOLOGY sparc


>Description:
	In Japan, the format of which sector size=1024, number of sector=8,
	number of track=77 was the most popular one especially for 130mm
	(5inch) FD for long time, because it was adopted by the Japanese
	best seller PC, NEC PC-9801 series (and also others, including x68k).
	It is still used widely in some situations.  This patch enables
	the device driver to handle this type of format.

	Because of the small MAXNPARTITIONS, this patch overrides the
	old PC diskette description.

	Note that, to handle this type of 90mm (3.5in) FD, you need
	a `3-mode' drive.  The builtin drive of recent model (after SS10?)
	of SPARC station (at least for Japanese market) is of 3-mode.

	To recognize NEC (Japanese) format MS-DOS disk, msdosfs must be
	modified as well.  See kern/2896.  Also I sent similar patch
	for i386 port. See port-i386/2895.

>How-To-Repeat:
>Fix:
*** fd.c.ORIG	Thu Jun 13 21:16:10 1996
--- fd.c	Mon Oct 28 18:11:48 1996
***************
*** 167,173 ****
--- 167,177 ----
  	{ 18,2,36,2,0xff,0xcf,0x1b,0x6c,80,2880,1,FDC_500KBPS,"1.44MB"    }, /* 1.44MB diskette */
  	{ 15,2,30,2,0xff,0xdf,0x1b,0x54,80,2400,1,FDC_500KBPS,"1.2MB"    }, /* 1.2 MB AT-diskettes */
  	{  9,2,18,2,0xff,0xdf,0x23,0x50,40, 720,2,FDC_300KBPS,"360KB/AT" }, /* 360kB in 1.2MB drive */
+ #ifndef FD_NEC_FORMAT
  	{  9,2,18,2,0xff,0xdf,0x2a,0x50,40, 720,1,FDC_250KBPS,"360KB/PC" }, /* 360kB PC diskettes */
+ #else
+         {  8,2,16,3,0xff,0xdf,0x35,0x74,77,1232,1,FDC_500KBPS, "1.2MB/NEC" }, /* 1.2 MB japanese format */
+ #endif
  	{  9,2,18,2,0xff,0xdf,0x2a,0x50,80,1440,1,FDC_250KBPS,"720KB"    }, /* 3.5" 720kB diskette */
  	{  9,2,18,2,0xff,0xdf,0x23,0x50,80,1440,1,FDC_300KBPS,"720KB/x"  }, /* 720kB in 1.2MB drive */
  	{  9,2,18,2,0xff,0xdf,0x2a,0x50,40, 720,2,FDC_250KBPS,"360KB/x"  }, /* 360kB in 720kB drive */
***************
*** 614,625 ****
  	int unit = FDUNIT(bp->b_dev);
  	int sz;
   	int s;
  
  	/* Valid unit, controller, and request? */
  	if (unit >= fd_cd.cd_ndevs ||
  	    (fd = fd_cd.cd_devs[unit]) == 0 ||
  	    bp->b_blkno < 0 ||
! 	    (bp->b_bcount % FDC_BSIZE) != 0) {
  		bp->b_error = EINVAL;
  		goto bad;
  	}
--- 618,631 ----
  	int unit = FDUNIT(bp->b_dev);
  	int sz;
   	int s;
+ 	int fd_bsize, bf;
  
  	/* Valid unit, controller, and request? */
  	if (unit >= fd_cd.cd_ndevs ||
  	    (fd = fd_cd.cd_devs[unit]) == 0 ||
  	    bp->b_blkno < 0 ||
! 	    (bp->b_bcount % (fd_bsize = 128 << fd->sc_type->secsize)) != 0 ||
! 	    (bp->b_blkno % (bf = fd_bsize / DEV_BSIZE)) != 0) {
  		bp->b_error = EINVAL;
  		goto bad;
  	}
***************
*** 628,637 ****
  	if (bp->b_bcount == 0)
  		goto done;
  
! 	sz = howmany(bp->b_bcount, FDC_BSIZE);
  
! 	if (bp->b_blkno + sz > fd->sc_type->size) {
! 		sz = fd->sc_type->size - bp->b_blkno;
  		if (sz == 0) {
  			/* If exactly at end of disk, return EOF. */
  			bp->b_resid = bp->b_bcount;
--- 634,643 ----
  	if (bp->b_bcount == 0)
  		goto done;
  
! 	sz = howmany(bp->b_bcount, DEV_BSIZE);
  
! 	if (bp->b_blkno + sz > fd->sc_type->size * bf) {
! 		sz = fd->sc_type->size * bf - bp->b_blkno;
  		if (sz == 0) {
  			/* If exactly at end of disk, return EOF. */
  			bp->b_resid = bp->b_bcount;
***************
*** 646,652 ****
  		bp->b_bcount = sz << DEV_BSHIFT;
  	}
  
!  	bp->b_cylin = bp->b_blkno / (FDC_BSIZE / DEV_BSIZE) / fd->sc_type->seccyl;
  
  #ifdef FD_DEBUG
  	if (fdc_debug > 1)
--- 652,658 ----
  		bp->b_bcount = sz << DEV_BSHIFT;
  	}
  
!  	bp->b_cylin = bp->b_blkno / (fd_bsize / DEV_BSIZE) / fd->sc_type->seccyl;
  
  #ifdef FD_DEBUG
  	if (fdc_debug > 1)
***************
*** 1128,1133 ****
--- 1134,1140 ----
  	struct buf *bp;
  	int read, head, sec, nblks;
  	struct fd_type *type;
+ 	int fd_bsize, bf;
  
  
  	if (fdc->sc_istate != ISTATE_IDLE) {
***************
*** 1149,1154 ****
--- 1156,1163 ----
  		fdc->sc_state = DEVIDLE;
   		return 0;
  	}
+ 	fd_bsize = fd->sc_type->secsize;
+ 	bf = fd_bsize / DEV_BSIZE;
  
  	/* Is there a transfer to this drive?  If not, deactivate drive. */
  	bp = fd->sc_q.b_actf;
***************
*** 1164,1170 ****
  		fdc->sc_errors = 0;
  		fd->sc_skip = 0;
  		fd->sc_bcount = bp->b_bcount;
! 		fd->sc_blkno = bp->b_blkno / (FDC_BSIZE / DEV_BSIZE);
  		untimeout(fd_motor_off, fd);
  		if ((fd->sc_flags & FD_MOTOR_WAIT) != 0) {
  			fdc->sc_state = MOTORWAIT;
--- 1173,1179 ----
  		fdc->sc_errors = 0;
  		fd->sc_skip = 0;
  		fd->sc_bcount = bp->b_bcount;
! 		fd->sc_blkno = bp->b_blkno / (fd_bsize / DEV_BSIZE);
  		untimeout(fd_motor_off, fd);
  		if ((fd->sc_flags & FD_MOTOR_WAIT) != 0) {
  			fdc->sc_state = MOTORWAIT;
***************
*** 1230,1239 ****
  		type = fd->sc_type;
  		sec = fd->sc_blkno % type->seccyl;
  		nblks = type->seccyl - sec;
! 		nblks = min(nblks, fd->sc_bcount / FDC_BSIZE);
! 		nblks = min(nblks, FDC_MAXIOSIZE / FDC_BSIZE);
  		fd->sc_nblks = nblks;
! 		fd->sc_nbytes = nblks * FDC_BSIZE;
  		head = sec / type->sectrac;
  		sec -= head * type->sectrac;
  #ifdef DIAGNOSTIC
--- 1239,1248 ----
  		type = fd->sc_type;
  		sec = fd->sc_blkno % type->seccyl;
  		nblks = type->seccyl - sec;
! 		nblks = min(nblks, fd->sc_bcount / fd_bsize);
! 		nblks = min(nblks, FDC_MAXIOSIZE / fd_bsize);
  		fd->sc_nblks = nblks;
! 		fd->sc_nbytes = nblks * fd_bsize;
  		head = sec / type->sectrac;
  		sec -= head * type->sectrac;
  #ifdef DIAGNOSTIC
***************
*** 1361,1367 ****
  		}
  		if (fdc->sc_errors) {
  			diskerr(bp, "fd", "soft error", LOG_PRINTF,
! 			    fd->sc_skip / FDC_BSIZE, (struct disklabel *)NULL);
  			printf("\n");
  			fdc->sc_errors = 0;
  		} else {
--- 1370,1376 ----
  		}
  		if (fdc->sc_errors) {
  			diskerr(bp, "fd", "soft error", LOG_PRINTF,
! 			    fd->sc_skip / fd_bsize, (struct disklabel *)NULL);
  			printf("\n");
  			fdc->sc_errors = 0;
  		} else {
***************
*** 1486,1492 ****
  
  	default:
  		diskerr(bp, "fd", "hard error", LOG_PRINTF,
! 		    fd->sc_skip / FDC_BSIZE, (struct disklabel *)NULL);
  
  		printf(" (st0 %b st1 %b st2 %b cyl %d head %d sec %d)\n",
  		    fdc->sc_status[0], NE7_ST0BITS,
--- 1495,1501 ----
  
  	default:
  		diskerr(bp, "fd", "hard error", LOG_PRINTF,
! 		    fd->sc_skip / DEV_BSIZE, (struct disklabel *)NULL);
  
  		printf(" (st0 %b st1 %b st2 %b cyl %d head %d sec %d)\n",
  		    fdc->sc_status[0], NE7_ST0BITS,
***************
*** 1628,1634 ****
  	bzero(lp, sizeof(struct cpu_disklabel));
  
  	lp->d_type = DTYPE_FLOPPY;
! 	lp->d_secsize = FDC_BSIZE;
  	lp->d_secpercyl = fd->sc_type->seccyl;
  	lp->d_nsectors = fd->sc_type->sectrac;
  	lp->d_ncylinders = fd->sc_type->tracks;
--- 1637,1643 ----
  	bzero(lp, sizeof(struct cpu_disklabel));
  
  	lp->d_type = DTYPE_FLOPPY;
! 	lp->d_secsize = 128 << fd->sc_type->secsize;
  	lp->d_secpercyl = fd->sc_type->seccyl;
  	lp->d_nsectors = fd->sc_type->sectrac;
  	lp->d_ncylinders = fd->sc_type->tracks;
>Audit-Trail:
>Unformatted: