Subject: kern/25440: Support for iRiver IFP-3xx flash MP3 players
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <mer@klockrike.net>
List: netbsd-bugs
Date: 05/02/2004 22:42:06
>Number:         25440
>Category:       kern
>Synopsis:       Open of the umass sd disk on iRiver flash players hangs
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun May 02 22:45:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Michael Eriksson
>Release:        NetBSD 1.6ZK
>Organization:
>Environment:
System: NetBSD kurtz 1.6ZK NetBSD 1.6ZK (KURTZ) #0: Sun Feb 22 12:53:04 CET 2004 mer@killy:/usr/src/sys/arch/i386/compile/KURTZ i386
Architecture: i386
Machine: i386
>Description:

Opening the umass sd disk of my iRiver iFP-390T flash-based MP3-player
hangs. This most likely applies also to other players in the iFP-3xx
series, and probably to other iRiver players as well. Only the iFP-3xx
series is included in the patch below; feedback from users of other
iRiver players should be collected, and the fix extended to include
them if needed.

>How-To-Repeat:

Try this on your iRiver iFP-390T:

datan# mount -t msdos /dev/sd0d /mnt

...and watch it just hang.

>Fix:

The hang at device open is caused by the iRiver iFP-390T's inability
to handle the PREVENT_ALLOW SCSI command. The patch below adds a new
quirk, and sets it for the iFP-3xx series.


Index: src/sys/dev/scsipi/scsipiconf.h
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/scsipiconf.h,v
retrieving revision 1.80
diff -u -r1.80 scsipiconf.h
--- scsipiconf.h	2003/09/18 00:06:34	1.80
+++ scsipiconf.h	2004/05/02 20:38:27
@@ -456,6 +456,7 @@
 #define PQUIRK_CAP_SYNC		0x00080000	/* SCSI device with ST sync op*/
 #define PQUIRK_CAP_WIDE16	0x00100000	/* SCSI device with ST wide op*/
 #define PQUIRK_CAP_NODT		0x00200000	/* signals DT, but can't. */
+#define PQUIRK_NOPREVENT	0x00400000	/* does not support PREVENT */
 
 
 /*
Index: src/sys/dev/scsipi/sd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/sd.c,v
retrieving revision 1.214
diff -u -r1.214 sd.c
--- sd.c	2003/12/23 13:12:25	1.214
+++ sd.c	2004/05/02 20:38:28
@@ -526,7 +526,8 @@
 
 		periph->periph_flags |= PERIPH_OPEN;
 
-		if (periph->periph_flags & PERIPH_REMOVABLE) {
+		if ((periph->periph_flags & PERIPH_REMOVABLE) &&
+		    (periph->periph_quirks & PQUIRK_NOPREVENT) == 0) {
 			/* Lock the pack in. */
 			error = scsipi_prevent(periph, PR_PREVENT,
 			    XS_CTL_IGNORE_ILLEGAL_REQUEST |
@@ -588,7 +589,8 @@
 
 bad:
 	if (sd->sc_dk.dk_openmask == 0) {
-		if (periph->periph_flags & PERIPH_REMOVABLE)
+		if ((periph->periph_flags & PERIPH_REMOVABLE) &&
+		    (periph->periph_quirks & PQUIRK_NOPREVENT) == 0)
 			scsipi_prevent(periph, PR_ALLOW,
 			    XS_CTL_IGNORE_ILLEGAL_REQUEST |
 			    XS_CTL_IGNORE_MEDIA_CHANGE);
@@ -652,7 +654,8 @@
 
 		scsipi_wait_drain(periph);
 
-		if (periph->periph_flags & PERIPH_REMOVABLE)
+		if ((periph->periph_flags & PERIPH_REMOVABLE) &&
+		    (periph->periph_quirks & PQUIRK_NOPREVENT) == 0)
 			scsipi_prevent(periph, PR_ALLOW,
 			    XS_CTL_IGNORE_ILLEGAL_REQUEST |
 			    XS_CTL_IGNORE_NOT_READY);
@@ -1139,15 +1142,15 @@
 			 * Don't force eject: check that we are the only
 			 * partition open. If so, unlock it.
 			 */
-			if ((sd->sc_dk.dk_openmask & ~(1 << part)) == 0 &&
-			    sd->sc_dk.dk_bopenmask + sd->sc_dk.dk_copenmask ==
-			    sd->sc_dk.dk_openmask) {
+			if ((sd->sc_dk.dk_openmask & ~(1 << part)) != 0 ||
+			    sd->sc_dk.dk_bopenmask + sd->sc_dk.dk_copenmask !=
+			    sd->sc_dk.dk_openmask)
+				return (EBUSY);
+			if ((periph->periph_quirks & PQUIRK_NOPREVENT) == 0) {
 				error = scsipi_prevent(periph, PR_ALLOW,
 				    XS_CTL_IGNORE_NOT_READY);
 				if (error)
 					return (error);
-			} else {
-				return (EBUSY);
 			}
 		}
 		/* FALLTHROUGH */
Index: src/sys/dev/usb/umass_quirks.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/umass_quirks.c,v
retrieving revision 1.64
diff -u -r1.64 umass_quirks.c
--- umass_quirks.c	2003/11/07 01:04:27	1.64
+++ umass_quirks.c	2004/05/02 20:38:40
@@ -161,6 +161,18 @@
 	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
 	  NULL, NULL
 	},
+
+	/*
+	 * iRiver UMS firmware version V1.11 for iFP-3xx can't handle
+	 * PREVENT requests.
+	 */
+	{ { USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_3XX },
+	  UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
+	  0,
+	  PQUIRK_NOPREVENT,
+	  UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
+	  NULL, NULL
+	},
 };
 
 const struct umass_quirk *
Index: src/sys/dev/usb/usbdevs
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usbdevs,v
retrieving revision 1.368
diff -u -r1.368 usbdevs
--- usbdevs	2004/02/19 01:10:42	1.368
+++ usbdevs	2004/05/02 20:38:41
@@ -389,6 +389,7 @@
 vendor DAISY		0x3579	Daisy Technology
 vendor NI		0x3923	National Instruments
 vendor IODATA2		0x40bb	I-O Data
+vendor IRIVER		0x4102	iRiver
 vendor ONSPEC2		0x55aa	OnSpec Electronic Inc.
 vendor INTEL		0x8086	Intel
 vendor HP2		0xf003	Hewlett Packard
@@ -902,6 +903,10 @@
 
 /* Intersil products */
 product INTERSIL PRISM_2X	0x3642	Prism2.x WLAN
+
+/* iRiver products */
+product IRIVER IFP_3XX		0x1103	iFP-3xx 
+product IRIVER IFP_5XX		0x1105	iFP-5xx 
 
 /* I-O DATA products */
 product IODATA IU_CD2		0x0204	DVD Multi-plus unit iU-CD2
Index: src/sys/dev/usb/usbdevs.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usbdevs.h,v
retrieving revision 1.371
diff -u -r1.371 usbdevs.h
--- usbdevs.h	2004/02/19 01:11:13	1.371
+++ usbdevs.h	2004/05/02 20:38:43
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdevs.h,v 1.371 2004/02/19 01:11:13 augustss Exp $	*/
+/*	$NetBSD$	*/
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -396,6 +396,7 @@
 #define	USB_VENDOR_DAISY	0x3579		/* Daisy Technology */
 #define	USB_VENDOR_NI	0x3923		/* National Instruments */
 #define	USB_VENDOR_IODATA2	0x40bb		/* I-O Data */
+#define	USB_VENDOR_IRIVER	0x4102		/* iRiver */
 #define	USB_VENDOR_ONSPEC2	0x55aa		/* OnSpec Electronic Inc. */
 #define	USB_VENDOR_INTEL	0x8086		/* Intel */
 #define	USB_VENDOR_HP2	0xf003		/* Hewlett Packard */
@@ -909,6 +910,10 @@
 
 /* Intersil products */
 #define	USB_PRODUCT_INTERSIL_PRISM_2X	0x3642		/* Prism2.x WLAN */
+
+/* iRiver products */
+#define	USB_PRODUCT_IRIVER_IFP_3XX	0x1103		/* iFP-3xx */
+#define	USB_PRODUCT_IRIVER_IFP_5XX	0x1105		/* iFP-5xx */
 
 /* I-O DATA products */
 #define	USB_PRODUCT_IODATA_IU_CD2	0x0204		/* DVD Multi-plus unit iU-CD2 */
Index: src/sys/dev/usb/usbdevs_data.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usbdevs_data.h,v
retrieving revision 1.372
diff -u -r1.372 usbdevs_data.h
--- usbdevs_data.h	2004/02/19 01:11:13	1.372
+++ usbdevs_data.h	2004/05/02 20:38:46
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdevs_data.h,v 1.372 2004/02/19 01:11:13 augustss Exp $	*/
+/*	$NetBSD$	*/
 
 /*
  * THIS FILE IS AUTOMATICALLY GENERATED.  DO NOT EDIT.
@@ -1954,6 +1954,18 @@
 	    "Prism2.x WLAN",
 	},
 	{
+	    USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_3XX,
+	    0,
+	    "iRiver",
+	    "iFP-3xx",
+	},
+	{
+	    USB_VENDOR_IRIVER, USB_PRODUCT_IRIVER_IFP_5XX,
+	    0,
+	    "iRiver",
+	    "iFP-5xx",
+	},
+	{
 	    USB_VENDOR_IODATA, USB_PRODUCT_IODATA_IU_CD2,
 	    0,
 	    "I-O Data",
@@ -6817,6 +6829,12 @@
 	    USB_VENDOR_IODATA2, 0,
 	    USB_KNOWNDEV_NOPROD,
 	    "I-O Data",
+	    NULL,
+	},
+	{
+	    USB_VENDOR_IRIVER, 0,
+	    USB_KNOWNDEV_NOPROD,
+	    "iRiver",
 	    NULL,
 	},
 	{
>Release-Note:
>Audit-Trail:
>Unformatted: