Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Oct 2004 02:21:56 -0700
From:      Bruce M Simpson <bms@spc.org>
To:        freebsd-current@FreeBSD.org
Subject:   Help wanted re formatting USB floppies.
Message-ID:  <20041006092156.GA690@empiric.icir.org>

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

--EuxKj2iCbKjpUGkD
Content-Type: multipart/mixed; boundary="vtzGhvizbBRQ85DL"
Content-Disposition: inline


--vtzGhvizbBRQ85DL
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

I am working on a hack to allow us to format floppies in USB drives.
Could willing volunteers do the following:

1) Apply the attached patch to your umass driver, rebuild, and reboot.
   The patch is relative to /usr i.e. above the src directory, and is
   against RELENG_5.

2) Plug in your USB floppy drive.

3) Repeat the following command with the new driver loaded, for various
   combinations of:
     a) No disk in the drive
     b) Unformatted disk in the drive
     c) Formatted disk in the drive (even better if you can do this
        for multiple combinations of 360KB, 720KB, 1.44MB)
   and report the results back to me:

	camcontrol cmd ${DEVNAME} -v \
	-c "23 00 00 00 00 00 00 00 20 00 00 00" \
	-i 0x20 "{} *i3 {Len} i1 {Blocks} i4 {} *b6 {Code} b2 {Blocklen} i3"

where ${DEVNAME} is the device name of your USB floppy (often da0 on laptop=
s).
You should get 4 numbers returned from this command, probably along the lin=
es
of: 32 2880 2 512.

4) Please do report the kind of disk, if you know what it is, that you got =
the
   result from, and the make/model of your USB floppy which you should be
   able to see from "usbdevs -v" as root.

Now I have a feeling what Windows does, when it encounters a USB floppy
device, is to use the READ_FORMAT_CAPACITY SCSI command to determine
which format(s) such a device supports; then read the flexible disk
geometry page to determine=20

Regards,
BMS

P.S. I did hack a diff for forcing camcontrol(8) to use a MODE_SENSE_10 or
MODE_SELECT_10 but it doesn't appear to do the right thing... the pages
have different layouts/sizes, so e.g. "Data bytes per sector" is actually
reported as "Starting cylinder-write precompensation". Could someone
more knowledgable with CAM or SCSI than I suggest a better way of looking
at the Flexible Disk Page?

--vtzGhvizbBRQ85DL
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="umass.diff"
Content-Transfer-Encoding: quoted-printable

Index: src/sys/dev/usb/umass.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/dev/usb/umass.c,v
retrieving revision 1.112.2.1
diff -u -p -r1.112.2.1 umass.c
--- src/sys/dev/usb/umass.c	20 Sep 2004 05:28:08 -0000	1.112.2.1
+++ src/sys/dev/usb/umass.c	6 Oct 2004 08:00:42 -0000
@@ -124,6 +124,7 @@
 #include <cam/cam_xpt_sim.h>
 #include <cam/scsi/scsi_all.h>
 #include <cam/scsi/scsi_da.h>
+#include <cam/scsi/scsi_ufi.h>
=20
 #include <cam/cam_periph.h>
=20
@@ -2888,6 +2889,7 @@ umass_ufi_transform(struct umass_softc *
 		}
 		return 1;
=20
+	case FORMAT_UNIT:	/* XXX */
 	case REZERO_UNIT:
 	case REQUEST_SENSE:
 	case INQUIRY:
@@ -2902,12 +2904,14 @@ umass_ufi_transform(struct umass_softc *
 	case MODE_SENSE_10:
 	case READ_12:
 	case WRITE_12:
+	case READ_FORMAT_CAPACITY:	/* XXX */
 		memcpy(*rcmd, cmd, cmdlen);
 		return 1;
=20
-	/* Other UFI commands: FORMAT_UNIT, READ_FORMAT_CAPACITY,
-	 * VERIFY, WRITE_AND_VERIFY.
+	/* Other UFI commands: VERIFY, WRITE_AND_VERIFY.
 	 * These should be checked whether they somehow can be made to fit.
+	 * XXX FORMAT_UNIT, READ_FORMAT_CAPACITY passed through above
+	 * without checking.
 	 */
=20
 	default:

--vtzGhvizbBRQ85DL
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="scsi_ufi.diff"

--- /dev/null	Wed Oct  6 01:33:00 2004
+++ src/sys/cam/scsi/scsi_ufi.h	Wed Oct  6 01:41:49 2004
@@ -0,0 +1,108 @@
+/*
+ * Structures and definitions for SCSI commands to UFI Floppy Devices,
+ * commonly used to format such devices.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef	_SCSI_SCSI_UFI_H
+#define _SCSI_SCSI_UFI_H 1
+
+#include <sys/cdefs.h>
+
+/*
+ * Opcodes
+ */
+#define	READ_FORMAT_CAPACITY	0x23
+#define	WRITE_AND_VERIFY	0x2E	/* XXX */
+#define	VERIFY			0x2F	/* XXX */
+
+/*
+ * READ_FORMAT_CAPACITY cdbs are *always* 12 bytes long,
+ * and must contain the LUN, and the length of the returned
+ * format capacity list which the host is able to handle.
+ */
+
+struct scsi_read_format_capacity
+{
+	uint8_t	opcode;		/* READ_FORMAT_CAPACITY */
+	uint8_t	lun;		/* top 3 bits contain LUN */
+	uint8_t	unused00[4];
+	uint8_t	alloc_len[2];	/* always scsi i.e. big endian */
+	uint8_t	unused01[3];
+};
+
+/*
+ * VERIFY is used to verify the physical disk medium. It is a 12-byte CDB.
+ * Replies to this come in through the usual sense key mechanism.
+ */
+
+struct scsi_verify
+{
+	uint8_t	opcode;		/* VERIFY */
+	uint8_t	lun;		/* All other bits should be zero */
+#define	SVFY_RELADR	0x01	/* Always 0 for UFI. */
+#define	SVFY_BYTECHK	0x02	/* Always 0 for UFI. */
+#define	SVFY_DPO	0x10	/* Always 0 for UFI. */
+#define	SVFY_LUN_MASK	0xE0	/* Top 3 MSBs are LUN */
+	uint8_t	addr[4];	/* LBA to begin verification at */
+	uint8_t	unused00[1];
+	uint8_t	len[4];		/* number of blocks to verify */
+	uint8_t	unused01[3];
+};
+
+/*
+ * WRITE_AND_VERIFY writes a track and verifies it.
+ * Replies to this come in through the usual sense key mechanism.
+ */
+
+struct scsi_write_and_verify
+{
+	uint8_t	opcode;		/* WRITE_AND_VERIFY */
+	uint8_t	lun;		/* All other bits should be zero */
+#define	SVFY_RELADR	0x01	/* Always 0 for UFI. */
+#define	SVFY_BYTECHK	0x02	/* Always 0 for UFI. */
+#define	SVFY_DPO	0x10	/* Always 0 for UFI. */
+#define	SVFY_LUN_MASK	0xE0	/* Top 3 MSBs are LUN */
+	uint8_t	addr[4];	/* LBA to begin verification at */
+	uint8_t	unused00[1];
+	uint8_t	len[4];		/* number of blocks to write and verify */
+	uint8_t	unused01[3];
+};
+
+/*
+ * Replies to READ_FORMAT_CAPACITY look like this:
+ *
+ * scsi_capacity_list_hdr
+ * scsi_capacity_descriptor (maximum/current)
+ *
+ * The appropriate csio_decode() format string looks like this:
+ * "{} *i3 {Len} i1 {Blocks} i4 {} *b6 {Code} b2 {Blocklen} i3"
+ *
+ * If the capacity list header length is greater than
+ * sizeof(struct format_capacity_descriptor), then there are
+ * additional format capacity descriptors available which
+ * denote which format(s) the drive can handle.
+ *
+ */
+
+struct format_capacity_list_header {
+	uint8_t	unused[3];
+	uint8_t	capacity_list_length;
+};
+
+struct format_capacity_descriptor {
+	uint8_t	num_blocks[4];	/* total number of LBAs */
+	uint8_t	code;		/* only present in max/cur descriptor */
+#define FCD_CODE_MASK	0x03	/* mask for code field above */
+#define FCD_UNFORMATTED	0x01	/* unformatted media present,
+				 * maximum capacity returned */
+#define FCD_FORMATTED	0x02	/* formatted media present,
+				 * current capacity returned */
+#define FCD_NOMEDIA	0x03	/* no media present,
+				 * maximum device capacity returned */
+	uint8_t	block_len[3];	/* length of an LBA in bytes */
+};
+
+#endif /* _SCSI_SCSI_UFI_H */

--vtzGhvizbBRQ85DL--

--EuxKj2iCbKjpUGkD
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Comment: ''

iD8DBQFBY7kzueUpAYYNtTsRAs+kAJ98gs+LHx04M3ljfN3vnd6z4O3z9QCgiwLn
DT/Uhy42n7JDWdX2fO99lMw=
=KmbO
-----END PGP SIGNATURE-----

--EuxKj2iCbKjpUGkD--



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