From: Marcelo Tosatti From: Alain Knaff This patch adds support for floppy disks whose sectors are numbered starting at 0 rather than 1 as usual disks would be. This format is used for some CP/M disks, and also for certain music samplers (such as Ensoniq Ensoniq EPS 16plus). In order to use it, you need an fdutils with the current patch from http://fdutils.linux.lu as well, and then do setfdrpm /dev/fd0 dd zerobased sect=10 or setfdprm /dev/fd0 hd zerobased sect. In addtion, the patch also fixes my email addresses. I no longer use pobox.com. --- 25-akpm/drivers/block/floppy.c | 19 +++++++++++++++---- 25-akpm/include/linux/fd.h | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff -puN drivers/block/floppy.c~support-zerobased-floppies drivers/block/floppy.c --- 25/drivers/block/floppy.c~support-zerobased-floppies 2004-04-03 03:00:05.350418168 -0800 +++ 25-akpm/drivers/block/floppy.c 2004-04-03 03:00:05.357417104 -0800 @@ -2258,6 +2258,10 @@ static void setup_format_params(int trac } } } + if(_floppy->stretch & FD_ZEROBASED) { + for(count = 0; count < F_SECT_PER_TRACK; count++) + here[count].sect--; + } } static void redo_format(void) @@ -2679,7 +2683,8 @@ static int make_raw_rw_request(void) } HEAD = fsector_t / _floppy->sect; - if (((_floppy->stretch & FD_SWAPSIDES) || TESTF(FD_NEED_TWADDLE)) && + if (((_floppy->stretch & (FD_SWAPSIDES | FD_ZEROBASED)) || + TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect) max_sector = _floppy->sect; @@ -2709,7 +2714,8 @@ static int make_raw_rw_request(void) GAP = _floppy->gap; CODE2SIZE; SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; - SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + 1; + SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + + ((_floppy->stretch & FD_ZEROBASED) ? 0 : 1); /* tracksize describes the size which can be filled up with sectors * of size ssize. @@ -3346,7 +3352,7 @@ static inline int set_geometry(unsigned g->track <= 0 || g->track > UDP->tracks>>STRETCH(g) || /* check if reserved bits are set */ - (g->stretch&~(FD_STRETCH|FD_SWAPSIDES)) != 0) + (g->stretch&~(FD_STRETCH|FD_SWAPSIDES|FD_ZEROBASED)) != 0) return -EINVAL; if (type){ if (!capable(CAP_SYS_ADMIN)) @@ -3367,11 +3373,13 @@ static inline int set_geometry(unsigned } up(&open_lock); } else { + int oldStretch; LOCK_FDC(drive,1); if (cmd != FDDEFPRM) /* notice a disk change immediately, else * we lose our settings immediately*/ CALL(poll_drive(1, FD_RAW_NEED_DISK)); + oldStretch = g->stretch; user_params[drive] = *g; if (buffer_drive == drive) SUPBOUND(buffer_max, user_params[drive].sect); @@ -3386,7 +3394,10 @@ static inline int set_geometry(unsigned * whose number will change. This is useful, because * mtools often changes the geometry of the disk after * looking at the boot block */ - if (DRS->maxblock > user_params[drive].sect || DRS->maxtrack) + if (DRS->maxblock > user_params[drive].sect || + DRS->maxtrack || + ((user_params[drive].sect ^ oldStretch) & + (FD_SWAPSIDES | FD_ZEROBASED))) invalidate_drive(bdev); else process_fd_request(); diff -puN include/linux/fd.h~support-zerobased-floppies include/linux/fd.h --- 25/include/linux/fd.h~support-zerobased-floppies 2004-04-03 03:00:05.351418016 -0800 +++ 25-akpm/include/linux/fd.h 2004-04-03 03:00:05.358416952 -0800 @@ -17,6 +17,7 @@ struct floppy_struct { stretch; /* !=0 means double track steps */ #define FD_STRETCH 1 #define FD_SWAPSIDES 2 +#define FD_ZEROBASED 4 unsigned char gap, /* gap1 size */ _