Subject: Re: kern/34737: NetBSD cannot mount a generation 5.5 iPod with Video
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Steve Woodford <scw@netbsd.org>
List: netbsd-bugs
Date: 10/07/2006 09:00:05
The following reply was made to PR kern/34737; it has been noted by GNATS.

From: Steve Woodford <scw@netbsd.org>
To: gnats-bugs@netbsd.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
	netbsd-bugs@netbsd.org
Subject: Re: kern/34737: NetBSD cannot mount a generation 5.5 iPod with Video
Date: Sat, 7 Oct 2006 09:57:52 +0100

 --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--