Subject: kern/27308: iRiver MP3 players can't be mounted
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <pierrick@bs-network.net>
List: netbsd-bugs
Date: 10/19/2004 23:13:10
>Number:         27308
>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:   Wed Oct 20 00:40:01 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Pierrick Brossin
>Release:        NetBSD 2.99.10
>Organization:
>Environment:
System: NetBSD lappy 2.99.10 NetBSD 2.99.10 (LAPPY) #2: Tue Oct 19 22:44:12 CEST 2004 root@lappy:/usr/obj/sys/arch/i386/compile/LAPPY i386
Architecture: i386
Machine: i386

>Description:
From bug 25440 (Michael Eriksson) on NetBSD 1.6ZK
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;
The hanging issue 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.

>How-To-Repeat:
mount -t msdos /dev/sd0d /mnt

>Fix:
diff -u usb/umass_quirks.c usb/umass_quirks.c
--- usb/umass_quirks.c  2004-10-19 22:51:21.000000000 +0200
+++ usb/umass_quirks.c  2004-10-19 22:50:54.000000000 +0200
@@ -185,6 +185,13 @@
          UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
          NULL, NULL
        },
+       { { 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 *
diff -u usb/usbdevs usb/usbdevs 
--- usb/usbdevs 2004-10-19 22:51:23.000000000 +0200     
+++ usb/usbdevs 2004-10-19 22:50:55.000000000 +0200     
@@ -393,6 +393,7 @@
 vendor DAISY           0x3579  Daisy Technology
 vendor NI              0x3923  National Instruments
 vendor IODATA2         0x40bb  I-O Data
+vendor IRIVER          0x4102  iRiver
 vendor DELL            0x413c  Dell
 vendor ONSPEC2         0x55aa  OnSpec Electronic Inc.
 vendor SITECOM         0x6189  Sitecom
@@ -922,6 +923,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
 product IODATA DVR_UEH8                0x0206  DVD Multi-plus unit DVR-UEH8
diff -u usb/usbdevs.h usb/usbdevs.h
--- usb/usbdevs.h       2004-10-19 22:51:24.000000000 +0200
+++ usb/usbdevs.h       2004-10-19 22:50:55.000000000 +0200
@@ -400,6 +400,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_DELL 0x413c          /* Dell */
 #define        USB_VENDOR_ONSPEC2      0x55aa          /* OnSpec Electronic Inc. */
 #define        USB_VENDOR_SITECOM      0x6189          /* Sitecom */
@@ -929,6 +930,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 */
 #define        USB_PRODUCT_IODATA_DVR_UEH8     0x0206          /* DVD Multi-plus unit DVR-UEH8 */
diff -u usb/usbdevs_data.h usb/usbdevs_data.h
--- usb/usbdevs_data.h  2004-10-19 22:51:24.000000000 +0200
+++ usb/usbdevs_data.h  2004-10-19 22:50:55.000000000 +0200
@@ -1996,6 +1996,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",
@@ -6928,6 +6940,12 @@
            NULL,
        },
        {
+           USB_VENDOR_IRIVER, 0,
+           USB_KNOWNDEV_NOPROD,
+           "iRiver",
+           NULL,
+       },
+       {
            USB_VENDOR_DELL, 0,
            USB_KNOWNDEV_NOPROD,
            "Dell",
diff -u scsipi/scsipiconf.h scsipi/scsipiconf.h
--- scsipi/scsipiconf.h 2004-10-19 22:51:39.000000000 +0200
+++ scsipi/scsipiconf.h 2004-10-19 22:51:06.000000000 +0200
@@ -452,6 +452,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 */


 /*
diff -u scsipi/sd.c scsipi/sd.c
--- scsipi/sd.c 2004-10-19 22:51:39.000000000 +0200
+++ scsipi/sd.c 2004-10-19 22:51:06.000000000 +0200
@@ -499,7 +499,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 |
@@ -563,7 +564,8 @@

  bad3:
        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);
@@ -625,7 +627,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);
@@ -1138,15 +1141,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 */

>Release-Note:
>Audit-Trail:
>Unformatted: