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