Пример #1
0
static int config_geom(Stream_t *Stream, struct device *dev, 
		       struct device *orig_dev, int media,
		       struct bootsector *boot)
{
	if(check_geom(dev, media, boot))
		return 1;
	set_geom(boot,dev);
	return 0;
}
Пример #2
0
dsk_err_t ntwdm_xwrite(DSK_DRIVER *self, const DSK_GEOMETRY *geom, const void *buf,
                              dsk_pcyl_t cylinder, dsk_phead_t head,
                              dsk_pcyl_t cyl_expected, dsk_phead_t head_expected,
                              dsk_psect_t sector, size_t sector_size, int deleted)
{
	NTWDM_DSK_DRIVER *ntself;
	FD_READ_WRITE_PARAMS rwp;
	LPVOID iobuffer;
	dsk_err_t err;
	DWORD dwIoCode;

	if (!self || !geom || !buf) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR;
	ntself = (NTWDM_DSK_DRIVER *)self;
	if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY;

	err = check_geom(ntself, geom);
	if (err) return err;

	rwp.flags = 0;
	if (!geom->dg_noskip)  rwp.flags |= FD_OPTION_SKIP;	      /* Skip deleted data */
	if (!geom->dg_fm)      rwp.flags |= FD_OPTION_MFM;	      /* MFM recording mode */
	if (!geom->dg_nomulti) rwp.flags |= FD_OPTION_MULTI_TRACK;    /* Enable multitrack */

	rwp.phead = encode_head(self, head);
	rwp.cyl = cyl_expected;
	rwp.head = head_expected;
	rwp.sector = sector;
	rwp.size = dsk_get_psh(sector_size);	/* [JCE] v1.1.5 */
	rwp.eot = sector+1;
	rwp.gap = geom->dg_rwgap;
	rwp.datalen = (sector_size < 255) ? sector_size : 0xFF;

	if (cylinder != ntself->nt_cylinder)
	{
		UCHAR cyl = ntself->nt_doublestep ? cylinder*2 : cylinder;
		if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SEEK, &cyl, sizeof(cyl),
				NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError());
		ntself->nt_cylinder = cylinder;
	}

/* v1.1.11: Use passed sector size, not geometry sector size */
        iobuffer = VirtualAlloc(NULL, sector_size, MEM_COMMIT, PAGE_READWRITE);
        if (!iobuffer) return DSK_ERR_NOMEM;
	memcpy(iobuffer, buf, sector_size);

	dwIoCode = deleted ? IOCTL_FDCMD_WRITE_DELETED_DATA : IOCTL_FDCMD_WRITE_DATA;
	if (!DeviceIoControl(ntself->nt_hdisk, dwIoCode, &rwp, sizeof(rwp), iobuffer,
			sector_size, &dwRet, NULL)) err = xlt_error(GetLastError());

	VirtualFree(iobuffer, 0, MEM_RELEASE);

	return err;
}
Пример #3
0
dsk_err_t linux_format(DSK_DRIVER *self, DSK_GEOMETRY *geom,
                                dsk_pcyl_t cylinder, dsk_phead_t head,
                                const DSK_FORMAT *format, unsigned char filler)
{
	struct floppy_raw_cmd raw_cmd;
	LINUX_DSK_DRIVER *lxself;
	int n;
	dsk_err_t err;
	unsigned char *buf;
	unsigned char mask = 0xFF;

	if (!self || !geom || !format) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR;
	lxself = (LINUX_DSK_DRIVER *)self;
	if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY;

	err = check_geom(lxself, geom);
	if (err) return err;
	if (geom->dg_fm)      mask &= ~0x40;
	if (geom->dg_nomulti) mask &= ~0x80;

	buf = dsk_malloc(geom->dg_sectors * 4);
	if (!buf) return DSK_ERR_NOMEM;
	for (n = 0; n < geom->dg_sectors; n++)
	{
		buf[n*4]   = format[n].fmt_cylinder;
		buf[n*4+1] = format[n].fmt_head;
		buf[n*4+2] = format[n].fmt_sector;
		buf[n*4+3] = dsk_get_psh(format[n].fmt_secsize);
	}

	init_raw_cmd(&raw_cmd);
	raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR;
	if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK;
	raw_cmd.track = cylinder;
	if (lxself->lx_doublestep) raw_cmd.track *= 2;
	raw_cmd.rate  = get_rate(geom);
	raw_cmd.length= 4 * geom->dg_sectors;
	raw_cmd.data  = buf;

	raw_cmd.cmd[raw_cmd.cmd_count++] = FD_FORMAT & mask;
	raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head);
	raw_cmd.cmd[raw_cmd.cmd_count++] = dsk_get_psh(geom->dg_secsize);
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_sectors;
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_fmtgap;
	raw_cmd.cmd[raw_cmd.cmd_count++] = filler;

	if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR;

	memcpy(lxself->lx_status, raw_cmd.reply, 4);
	if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply);
	lxself->lx_cylinder = cylinder;
	return DSK_ERR_OK;
}
Пример #4
0
dsk_err_t linux_xread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf,
                              dsk_pcyl_t cylinder, dsk_phead_t head,
                              dsk_pcyl_t cyl_expected, dsk_phead_t head_expected,
                              dsk_psect_t sector, size_t sector_size, int *deleted)
{
	struct floppy_raw_cmd raw_cmd;
	LINUX_DSK_DRIVER *lxself;
	dsk_err_t err;
	unsigned char mask = 0xFF;

	if (!self || !geom || !buf) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR;
	lxself = (LINUX_DSK_DRIVER *)self;
	if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY;

	err = check_geom(lxself, geom);
	if (err) return err;

	if (geom->dg_noskip)  mask &= ~0x20;	/* Don't skip deleted data */
	if (geom->dg_fm)      mask &= ~0x40;	/* FM recording mode */
	if (geom->dg_nomulti) mask &= ~0x80;	/* Disable multitrack */

	init_raw_cmd(&raw_cmd);
	raw_cmd.flags = FD_RAW_READ | FD_RAW_INTR;
	if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK;
	raw_cmd.track = cylinder;
	if (lxself->lx_doublestep) raw_cmd.track *= 2;
	raw_cmd.rate  = get_rate(geom);
	raw_cmd.length= sector_size;
	raw_cmd.data  = buf;

	if (deleted && (*deleted))
			raw_cmd.cmd[raw_cmd.cmd_count++] = 0xEC    & mask;
	else		raw_cmd.cmd[raw_cmd.cmd_count++] = FD_READ & mask;
	raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head);
	raw_cmd.cmd[raw_cmd.cmd_count++] = cyl_expected;
	raw_cmd.cmd[raw_cmd.cmd_count++] = head_expected;
	raw_cmd.cmd[raw_cmd.cmd_count++] = sector;
	raw_cmd.cmd[raw_cmd.cmd_count++] = dsk_get_psh(sector_size);
	raw_cmd.cmd[raw_cmd.cmd_count++] = sector;
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_rwgap;
	raw_cmd.cmd[raw_cmd.cmd_count++] = (sector_size < 255) ? sector_size : 0xFF; 

	if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR;

	memcpy(lxself->lx_status, raw_cmd.reply, 4);
	if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply);

	if (deleted) deleted[0] = (raw_cmd.reply[2] & 0x40) ? 1 : 0;
	lxself->lx_cylinder = cylinder;
	return DSK_ERR_OK;
}
Пример #5
0
dsk_err_t ntwdm_format(DSK_DRIVER *self, DSK_GEOMETRY *geom,
                                dsk_pcyl_t cylinder, dsk_phead_t head,
                                const DSK_FORMAT *format, unsigned char filler)
{
	NTWDM_DSK_DRIVER *ntself;
	unsigned u, fsize;
	dsk_err_t err;
	FD_FORMAT_PARAMS *pfp;
	FD_ID_HEADER *ph;

	if (!self || !geom || !format) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR;
	ntself = (NTWDM_DSK_DRIVER *)self;
	if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY;

	err = check_geom(ntself, geom);
	if (err) return err;

	fsize = sizeof(FD_FORMAT_PARAMS) + geom->dg_sectors * sizeof(FD_ID_HEADER);
	pfp = (FD_FORMAT_PARAMS *)dsk_malloc(fsize);
	if (!pfp) return DSK_ERR_NOMEM;
	pfp->flags   = geom->dg_fm ? 0 : FD_OPTION_MFM;
	pfp->phead   = encode_head(self, head);
	pfp->size    = dsk_get_psh(geom->dg_secsize);
	pfp->sectors = geom->dg_sectors;
	pfp->gap     = geom->dg_fmtgap;
	pfp->fill    = filler;

	ph = (FD_ID_HEADER *)(pfp+1);
	for (u = 0; u < geom->dg_sectors; u++)
	{
		ph[u].cyl    = format[u].fmt_cylinder;
		ph[u].head   = format[u].fmt_head;
		ph[u].sector = format[u].fmt_sector;
		ph[u].size   = dsk_get_psh(format[u].fmt_secsize);
	}

	if (cylinder != ntself->nt_cylinder)
	{
		UCHAR cyl = ntself->nt_doublestep ? cylinder*2 : cylinder;
		if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SEEK, &cyl, sizeof(cyl),
				NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError());
		ntself->nt_cylinder = cylinder;
	}

	if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_FORMAT_TRACK, pfp, fsize,
			NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError());

	return DSK_ERR_OK;
}
Пример #6
0
/* Read a track (FDC765 READ TRACK command) */
dsk_err_t linux_xtread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf,
                              dsk_pcyl_t cylinder, dsk_phead_t head,
			      dsk_pcyl_t cyl_expected, dsk_phead_t head_expected)
{
	struct floppy_raw_cmd raw_cmd;
	LINUX_DSK_DRIVER *lxself;
	dsk_err_t err;
	unsigned char mask = 0xFF;

	if (!self || !geom || !buf) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR;
	lxself = (LINUX_DSK_DRIVER *)self;
	if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY;

	err = check_geom(lxself, geom);
	if (err) return err;

	if (geom->dg_fm)      mask &= ~0x40;
	if (geom->dg_nomulti) mask &= ~0x80;

	init_raw_cmd(&raw_cmd);
	raw_cmd.flags = FD_RAW_READ | FD_RAW_INTR;
	if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK;
	raw_cmd.track = cylinder;
	if (lxself->lx_doublestep) raw_cmd.track *= 2;
	raw_cmd.rate  = get_rate(geom);
	raw_cmd.length= geom->dg_secsize * geom->dg_sectors;
	raw_cmd.data  = buf;
	
	/* fdreg.h doesn't define the Read Track command, but here it is */	
	raw_cmd.cmd[raw_cmd.cmd_count++] = 0x62 & mask;
	raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head);
	raw_cmd.cmd[raw_cmd.cmd_count++] = cyl_expected;
	raw_cmd.cmd[raw_cmd.cmd_count++] = head_expected;
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_secbase;
	raw_cmd.cmd[raw_cmd.cmd_count++] = dsk_get_psh(geom->dg_secsize);
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_secbase + geom->dg_sectors;
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_rwgap;
	raw_cmd.cmd[raw_cmd.cmd_count++] = 0xFF;

	if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR;

	memcpy(lxself->lx_status, raw_cmd.reply, 4);
	if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply);
	lxself->lx_cylinder = cylinder;
	return DSK_ERR_OK;
}
Пример #7
0
/* Read a track (FDC765 READ TRACK command) */
dsk_err_t ntwdm_xtread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf,
                              dsk_pcyl_t cylinder, dsk_phead_t head,
			      dsk_pcyl_t cyl_expected, dsk_phead_t head_expected)
{
	NTWDM_DSK_DRIVER *ntself;
	FD_READ_WRITE_PARAMS rwp;
	LPVOID iobuffer;
	DWORD tracksize;
	dsk_err_t err;

	if (!self || !geom || !buf) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR;
	ntself = (NTWDM_DSK_DRIVER *)self;
	if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY;

	err = check_geom(ntself, geom);
	if (err) return err;

	rwp.flags = 0;
	if (!geom->dg_fm)      rwp.flags |= FD_OPTION_MFM;	      /* MFM recording mode */
	if (!geom->dg_nomulti) rwp.flags |= FD_OPTION_MULTI_TRACK;    /* Enable multitrack */

	rwp.phead = encode_head(self, head);
	rwp.cyl = cyl_expected;
	rwp.head = head_expected;
	rwp.sector = geom->dg_secbase;
	rwp.size = dsk_get_psh(geom->dg_secsize);
	rwp.eot = geom->dg_secbase + geom->dg_sectors;
	rwp.gap = geom->dg_rwgap;
	rwp.datalen = 0xFF;

	tracksize = rwp.size * geom->dg_sectors;
        iobuffer = VirtualAlloc(NULL, tracksize, MEM_COMMIT, PAGE_READWRITE);
        if (!iobuffer) return DSK_ERR_NOMEM;

	if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_READ_TRACK, &rwp, sizeof(rwp),
			iobuffer, geom->dg_secsize, &dwRet, NULL)) err = xlt_error(GetLastError());

	memcpy(buf, iobuffer, geom->dg_secsize);
	VirtualFree(iobuffer, 0, MEM_RELEASE);

	return err;
}
Пример #8
0
dsk_err_t linux_secid(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
                                dsk_pcyl_t cylinder, dsk_phead_t head,
                                DSK_FORMAT *result)
{
	struct floppy_raw_cmd raw_cmd;
	LINUX_DSK_DRIVER *lxself;
	unsigned char mask = 0xFF;
	dsk_err_t err;

	if (!self || !geom || !result) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR;
	lxself = (LINUX_DSK_DRIVER *)self;
	if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY;

	if (geom->dg_fm)      mask &= ~0x40;
	if (geom->dg_nomulti) mask &= ~0x80;

/* [v0.8.3] It was necessary to add this check correctly to detect 100k 
 * FM-recorded discs in a 5.25" drive */
	err = check_geom(lxself, geom);
	if (err) return err;

	init_raw_cmd(&raw_cmd);
	raw_cmd.flags = FD_RAW_INTR;
	if (cylinder != lxself->lx_cylinder)  raw_cmd.flags |= FD_RAW_NEED_SEEK;
	raw_cmd.track = cylinder;
	if (lxself->lx_doublestep) raw_cmd.track *= 2;
	raw_cmd.rate  = get_rate(geom);
	raw_cmd.cmd[raw_cmd.cmd_count++] = FD_READID & mask;
	raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head);

	if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR;

	memcpy(lxself->lx_status, raw_cmd.reply, 4);
	if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply);
	result->fmt_cylinder = raw_cmd.reply[3];	
	result->fmt_head     = raw_cmd.reply[4];	
	result->fmt_sector   = raw_cmd.reply[5];	
	result->fmt_secsize  = 128 << raw_cmd.reply[6];	
	lxself->lx_cylinder = cylinder;
	return DSK_ERR_OK;
}
Пример #9
0
dsk_err_t ntwdm_secid(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
                                dsk_pcyl_t cylinder, dsk_phead_t head,
                                DSK_FORMAT *result)
{
	NTWDM_DSK_DRIVER *ntself;
	FD_READ_ID_PARAMS rip;
	FD_CMD_RESULT res;
	dsk_err_t err;

	if (!self || !geom || !result) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR;
	ntself = (NTWDM_DSK_DRIVER *)self;
	if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY;

	err = check_geom(ntself, geom);
	if (err) return err;

	if (cylinder != ntself->nt_cylinder)
	{
		UCHAR cyl = ntself->nt_doublestep ? cylinder*2 : cylinder;
		if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SEEK, &cyl, sizeof(cyl),
				NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError());
		ntself->nt_cylinder = cylinder;
	}

	rip.flags = geom->dg_fm ? 0 : FD_OPTION_MFM;
	rip.head  = encode_head(self, head);
	if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_READ_ID, &rip, sizeof(rip),
			&res, sizeof(res), &dwRet, NULL)) return xlt_error(GetLastError());

	result->fmt_cylinder = res.cyl;
	result->fmt_head     = res.head;
	result->fmt_sector   = res.sector;
	result->fmt_secsize  = 128 << res.size;	

	return DSK_ERR_OK;
}
Пример #10
0
Stream_t *XdfOpen(struct device *dev, char *name,
		  int mode, char *errmsg, struct xdf_info *info)
{
	Xdf_t *This;
	off_t begin, end;
	struct bootsector *boot;
	int type;

	if(dev && (!SHOULD_USE_XDF(dev) || check_geom(dev, 0, 0)))
		return NULL;

	This = New(Xdf_t);
	if (!This)
		return NULL;

	This->Class = &XdfClass;
	This->sector_size = 512;
	This->stretch = 0;

	precmd(dev);
	This->fd = open(name, mode | dev->mode | O_EXCL | O_NDELAY);
	if(This->fd < 0) {
#ifdef HAVE_SNPRINTF
		snprintf(errmsg,199,"xdf floppy: open: \"%s\"", strerror(errno));
#else
		sprintf(errmsg,"xdf floppy: open: \"%s\"", strerror(errno));
#endif
		goto exit_0;
	}
	closeExec(This->fd);

	This->drive = GET_DRIVE(This->fd);
	if(This->drive < 0)
		goto exit_1;

	/* allocate buffer */
	This->buffer = (char *) malloc(96 * 512);
	if (!This->buffer)
		goto exit_1;

	This->current_track = -1;
	This->track_map = (TrackMap_t *)
		calloc(96, sizeof(TrackMap_t));
	if(!This->track_map)
		goto exit_2;

	/* lock the device on writes */
	if (lock_dev(This->fd, mode == O_RDWR, dev)) {
#ifdef HAVE_SNPRINTF
		snprintf(errmsg,199,"xdf floppy: device \"%s\" busy:", 
			dev->name);
#else
		sprintf(errmsg,"xdf floppy: device \"%s\" busy:", 
			dev->name);
#endif
		goto exit_3;
	}

	/* Before reading the boot sector, assume dummy values suitable
	 * for reading at least the boot sector */
	This->track_size = 11;
	This->track0_size = 6;
	This->rate = 0;
	This->FatSize = 9;
	This->RootDirSize = 1;
	decompose(This, 0, 512, &begin, &end, 0);
	if (load_data(This, 0, 1, 1) < 0 ) {
		This->rate = 0x43;
		if(load_data(This, 0, 1, 1) < 0)
			goto exit_3;
	}

	boot = (struct bootsector *) This->buffer;
	This->FatSize = WORD(fatlen);
	This->RootDirSize = WORD(dirents)/16;
	This->track_size = WORD(nsect);
	for(type=0; type < NUMBER(xdf_table); type++) {
		if(xdf_table[type].track_size == This->track_size) {
			This->map = xdf_table[type].map;
			This->track0_size = xdf_table[type].track0_size;
			This->rootskip = xdf_table[type].rootskip;
			break;
		}
	}
	if(type == NUMBER(xdf_table))
		goto exit_3;

	if(info) {
		info->RootDirSize = This->RootDirSize;
		info->FatSize = This->FatSize;
		info->BadSectors = 5;
	}
	decompose(This, 0, 512, &begin, &end, 1);

	This->refs = 1;
	This->Next = 0;
	This->Buffer = 0;
	if(dev)
		set_geom(boot, dev);
	return (Stream_t *) This;

exit_3:
	Free(This->track_map);
exit_2:
	Free(This->buffer);
exit_1:
	close(This->fd);
exit_0:
	Free(This);
	return NULL;
}