Subject: Re: kern/34737: NetBSD cannot mount a generation 5.5 iPod with Video
To: None <gnats-bugs@netbsd.org>
From: Steve Woodford <scw@netbsd.org>
List: netbsd-bugs
Date: 10/07/2006 09:57:52
--Boundary-00=_Qw2JFAAcwj5Av/B
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Friday 06 October 2006 23:00, David W. Talmage wrote:

> NetBSD cannot mount a 30GB generation 5.5 iPod with Video.  All
> attempts to access the iPod hang in biowait.
>
> When I plug in my iPod, NetBSD creates an incorrect geometry for the
> iPod.

Can you try again after applying the attached patch under sys/dev/scsipi?

If my hunch is right, this will solve the geometry and hanging issues, 
but it will uncover another limitation with the kernel. Namely the 
DEV_BSIZE issue described at the following link:

http://www.sra.co.jp/people/soda/koji/sectorsize-en.txt

Cheers, Steve

--Boundary-00=_Qw2JFAAcwj5Av/B
Content-Type: text/x-diff;
  charset="iso-8859-1";
  name="scsipi-blksize.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="scsipi-blksize.diff"

Index: scsipi_base.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/scsipi_base.c,v
retrieving revision 1.137
diff -u -r1.137 scsipi_base.c
--- scsipi_base.c	11 Sep 2006 19:43:55 -0000	1.137
+++ scsipi_base.c	7 Oct 2006 08:52:54 -0000
@@ -1025,7 +1025,7 @@
  *	Find out from the device what its capacity is.
  */
 u_int64_t
-scsipi_size(struct scsipi_periph *periph, int flags)
+scsipi_size(struct scsipi_periph *periph, int *secsize, int flags)
 {
 	union {
 		struct scsipi_read_capacity_10 cmd;
@@ -1048,8 +1048,11 @@
 	    flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK | XS_CTL_SILENT) != 0)
 		return (0);
 
-	if (_4btol(data.data.addr) != 0xffffffff)
+	if (_4btol(data.data.addr) != 0xffffffff) {
+		if (secsize)
+			*secsize = _4btol(data.data.length);
 		return (_4btol(data.data.addr) + 1);
+	}
 
 	/*
 	 * Device is larger than can be reflected by READ CAPACITY (10).
@@ -1067,6 +1070,8 @@
 	    flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK | XS_CTL_SILENT) != 0)
 		return (0);
 
+	if (secsize)
+		*secsize = _4btol(data.data.length);
 	return (_8btol(data.data16.addr) + 1);
 }
 
Index: scsipiconf.h
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/scsipiconf.h,v
retrieving revision 1.103
diff -u -r1.103 scsipiconf.h
--- scsipiconf.h	16 Feb 2006 20:17:19 -0000	1.103
+++ scsipiconf.h	7 Oct 2006 08:52:54 -0000
@@ -638,7 +638,7 @@
 const char *scsipi_dtype(int);
 void	scsipi_strvis(u_char *, int, const u_char *, int);
 int	scsipi_execute_xs(struct scsipi_xfer *);
-u_int64_t scsipi_size(struct scsipi_periph *, int);
+u_int64_t scsipi_size(struct scsipi_periph *, int *, int);
 int	scsipi_test_unit_ready(struct scsipi_periph *, int);
 int	scsipi_prevent(struct scsipi_periph *, int, int);
 int	scsipi_inquire(struct scsipi_periph *,
Index: sd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/sd.c,v
retrieving revision 1.250
diff -u -r1.250 sd.c
--- sd.c	14 Sep 2006 17:54:34 -0000	1.250
+++ sd.c	7 Oct 2006 08:52:55 -0000
@@ -1651,7 +1651,7 @@
 		u_int8_t resvd;
 	} scsipi_sense;
 	u_int64_t sectors;
-	int error;
+	int error, blksize;
 
 	/*
 	 * scsipi_size (ie "read capacity") and mode sense page 6
@@ -1660,7 +1660,7 @@
 	 * XXX probably differs for removable media
 	 */
 	dp->blksize = 512;
-	if ((sectors = scsipi_size(sd->sc_periph, flags)) == 0)
+	if ((sectors = scsipi_size(sd->sc_periph, &blksize, flags)) == 0)
 		return (SDGP_RESULT_OFFLINE);		/* XXX? */
 
 	error = scsipi_mode_sense(sd->sc_periph, SMS_DBD, 6,
@@ -1672,7 +1672,7 @@
 
 	dp->blksize = _2btol(scsipi_sense.lbs);
 	if (dp->blksize == 0)
-		dp->blksize = 512;
+		dp->blksize = blksize ? blksize : 512;
 
 	/*
 	 * Create a pseudo-geometry.
@@ -1700,13 +1700,13 @@
 sd_get_capacity(struct sd_softc *sd, struct disk_parms *dp, int flags)
 {
 	u_int64_t sectors;
-	int error;
+	int error, blksize;
 #if 0
 	int i;
 	u_int8_t *p;
 #endif
 
-	dp->disksize = sectors = scsipi_size(sd->sc_periph, flags);
+	dp->disksize = sectors = scsipi_size(sd->sc_periph, &blksize, flags);
 	if (sectors == 0) {
 		struct scsipi_read_format_capacities cmd;
 		struct {
@@ -1752,7 +1752,7 @@
 
 		dp->blksize = _3btol(data.desc.blklen);
 		if (dp->blksize == 0)
-			dp->blksize = 512;
+			dp->blksize = blksize ? blksize : 512;
 	} else {
 		struct sd_mode_sense_data scsipi_sense;
 		int big, bsize;
@@ -1761,7 +1761,7 @@
 		memset(&scsipi_sense, 0, sizeof(scsipi_sense));
 		error = sd_mode_sense(sd, 0, &scsipi_sense,
 		    sizeof(scsipi_sense.blk_desc), 0, flags | XS_CTL_SILENT, &big);
-		dp->blksize = 512;
+		dp->blksize = blksize ? blksize : 512;
 		if (!error) {
 			if (big) {
 				bdesc = (void *)(&scsipi_sense.header.big + 1);
@@ -1780,7 +1780,7 @@
 			if (bsize >= 8) {
 				dp->blksize = _3btol(bdesc->blklen);
 				if (dp->blksize == 0)
-					dp->blksize = 512;
+					dp->blksize = blksize ? blksize : 512;
 			}
 		}
 	}

--Boundary-00=_Qw2JFAAcwj5Av/B--