Subject: port-i386/2895: i386 fd.c patch to recognize NEC (Japanese) format.
To: None <gnats-bugs@gnats.netbsd.org>
From: MINOURA Makoto <minoura@kw.netlaputa.or.jp>
List: netbsd-bugs
Date: 10/27/1996 23:51:56
>Number:         2895
>Category:       port-i386
>Synopsis:       i386 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:   Sun Oct 27 07:05:00 1996
>Last-Modified:
>Originator:     MINOURA Makoto
>Organization:
MINOURA, Makoto <minoura@kw.netlaputa.or.jp>
Nakahara-ku Kawasaki-Shi, JAPAN
>Release:        1.2
>Environment:
System: NetBSD daisy 1.2 NetBSD 1.2 (DAISY) #25: Sun Oct 27 22:15:03 JST 1996 root@daisy:/usr/src/sys/arch/i386/compile/DAISY i386


>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.  Hopefully, MAXNPARTITIONS should
	be increased to 16 or some.

	To recognize NEC (Japanese) format MS-DOS disk, msdosfs must be
	modified as well.  I'll send a patch as another report.

	For FFS, see PR bin/2404.
>How-To-Repeat:
>Fix:
*** fd.c.ORIG	Sat Aug 31 20:35:24 1996
--- fd.c	Sun Oct 27 16:28:40 1996
***************
*** 149,155 ****
--- 149,159 ----
          { 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/[1024bytes/sector]"    }, /* 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 */
***************
*** 486,492 ****
--- 490,502 ----
  	case NVRAM_DISKETTE_144M:
  		return &fd_types[0];
  	case NVRAM_DISKETTE_360K:
+ #ifdef FD_NEC_FORMAT
+ 	        printf ("%s: drive %d: kernel does not configured to recognize this type of drive.\n",
+ 		    fdc, drive);
+ 		return NULL;
+ #else
  		return &fd_types[3];
+ #endif
  	case NVRAM_DISKETTE_720K:
  		return &fd_types[4];
  	default:
***************
*** 515,524 ****
  	struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(bp->b_dev)];
  	int sz;
   	int s;
  
  	/* Valid unit, controller, and request? */
  	if (bp->b_blkno < 0 ||
! 	    (bp->b_bcount % FDC_BSIZE) != 0) {
  		bp->b_error = EINVAL;
  		goto bad;
  	}
--- 525,537 ----
  	struct fd_softc *fd = fd_cd.cd_devs[FDUNIT(bp->b_dev)];
  	int sz;
   	int s;
+ 	int fd_bsize = 128 << fd->sc_type->secsize;
+ 	int bf = fd_bsize / DEV_BSIZE;
  
  	/* Valid unit, controller, and request? */
  	if (bp->b_blkno < 0 ||
! 	    (bp->b_blkno % bf) != 0 ||
! 	    (bp->b_bcount % fd_bsize) != 0) {
  		bp->b_error = EINVAL;
  		goto bad;
  	}
***************
*** 527,536 ****
  	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. */
  			goto done;
--- 540,549 ----
  	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. */
  			goto done;
***************
*** 544,550 ****
  		bp->b_bcount = sz << DEV_BSHIFT;
  	}
  
!  	bp->b_cylin = bp->b_blkno / (FDC_BSIZE / DEV_BSIZE) / fd->sc_type->seccyl;
  
  #ifdef FD_DEBUG
  	printf("fdstrategy: b_blkno %d b_bcount %d blkno %d cylin %d sz %d\n",
--- 557,563 ----
  		bp->b_bcount = sz << DEV_BSHIFT;
  	}
  
!  	bp->b_cylin = bp->b_blkno / (fd_bsize / DEV_BSIZE) / fd->sc_type->seccyl;
  
  #ifdef FD_DEBUG
  	printf("fdstrategy: b_blkno %d b_bcount %d blkno %d cylin %d sz %d\n",
***************
*** 884,889 ****
--- 897,903 ----
  	bus_io_handle_t ioh = fdc->sc_ioh;
  	int read, head, sec, i, nblks;
  	struct fd_type *type;
+ 	int fd_bsize, bf;
  
  loop:
  	/* Is there a drive for the controller to do a transfer with? */
***************
*** 892,897 ****
--- 906,913 ----
  		fdc->sc_state = DEVIDLE;
   		return 1;
  	}
+ 	fd_bsize = 128 << fd->sc_type->secsize;
+ 	bf = fd_bsize / FDC_BSIZE;
  
  	/* Is there a transfer to this drive?  If not, deactivate drive. */
  	bp = fd->sc_q.b_actf;
***************
*** 907,913 ****
  		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;
--- 923,929 ----
  		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;
***************
*** 958,967 ****
  		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
--- 974,983 ----
  		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
***************
*** 1072,1078 ****
  #endif
  		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;
  		}
--- 1088,1094 ----
  #endif
  		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;
  		}
***************
*** 1174,1180 ****
  
  	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,
  		    fdc->sc_status[1], NE7_ST1BITS,
--- 1190,1197 ----
  
  	default:
  		diskerr(bp, "fd", "hard error", LOG_PRINTF,
! 		    fd->sc_skip / (128 << fd->sc_type->secsize),
! 		    (struct disklabel *)NULL);
  		printf(" (st0 %b st1 %b st2 %b cyl %d head %d sec %d)\n",
  		    fdc->sc_status[0], NE7_ST0BITS,
  		    fdc->sc_status[1], NE7_ST1BITS,
***************
*** 1227,1233 ****
  
  		buffer.d_secpercyl = fd->sc_type->seccyl;
  		buffer.d_type = DTYPE_FLOPPY;
! 		buffer.d_secsize = FDC_BSIZE;
  
  		if (readdisklabel(dev, fdstrategy, &buffer, NULL) != NULL)
  			return EINVAL;
--- 1244,1250 ----
  
  		buffer.d_secpercyl = fd->sc_type->seccyl;
  		buffer.d_type = DTYPE_FLOPPY;
! 		buffer.d_secsize = 128 << fd->sc_type->secsize;
  
  		if (readdisklabel(dev, fdstrategy, &buffer, NULL) != NULL)
  			return EINVAL;


>Audit-Trail:
>Unformatted: