From owner-svn-src-all@FreeBSD.ORG Sun Jan 17 18:31:27 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DD705106566B; Sun, 17 Jan 2010 18:31:27 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CA7928FC15; Sun, 17 Jan 2010 18:31:27 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o0HIVRQ1009691; Sun, 17 Jan 2010 18:31:27 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0HIVRwC009686; Sun, 17 Jan 2010 18:31:27 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <201001171831.o0HIVRwC009686@svn.freebsd.org> From: Andrew Thompson Date: Sun, 17 Jan 2010 18:31:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202510 - in stable/8/sys/dev/usb: . serial X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 Jan 2010 18:31:28 -0000 Author: thompsa Date: Sun Jan 17 18:31:27 2010 New Revision: 202510 URL: http://svn.freebsd.org/changeset/base/202510 Log: MFC r201681 Improve u3g device ejecting by providing additional methods for the eject command in the usb_msctest routines, as well as a general tidyup. Modified: stable/8/sys/dev/usb/serial/u3g.c stable/8/sys/dev/usb/usb_device.c stable/8/sys/dev/usb/usb_msctest.c stable/8/sys/dev/usb/usb_msctest.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/dev/usb/serial/u3g.c ============================================================================== --- stable/8/sys/dev/usb/serial/u3g.c Sun Jan 17 18:30:37 2010 (r202509) +++ stable/8/sys/dev/usb/serial/u3g.c Sun Jan 17 18:31:27 2010 (r202510) @@ -86,10 +86,14 @@ SYSCTL_INT(_hw_usb_u3g, OID_AUTO, debug, #define U3GSP_HSPA 6 #define U3GSP_MAX 7 -#define U3GFL_HUAWEI_INIT 0x0001 /* Init command required */ -#define U3GFL_SCSI_EJECT 0x0002 /* SCSI eject command required */ -#define U3GFL_SIERRA_INIT 0x0004 /* Init command required */ -#define U3GFL_SAEL_M460_INIT 0x0008 /* Init device */ +#define U3GINIT_HUAWEI 1 /* Requires Huawei init command */ +#define U3GINIT_SIERRA 2 /* Requires Sierra init command */ +#define U3GINIT_SCSIEJECT 3 /* Requires SCSI eject command */ +#define U3GINIT_REZERO 4 /* Requires SCSI rezero command */ +#define U3GINIT_ZTESTOR 5 /* Requires ZTE SCSI command */ +#define U3GINIT_CMOTECH 6 /* Requires CMOTECH SCSI command */ +#define U3GINIT_WAIT 7 /* Device reappears after a delay */ +#define U3GINIT_SAEL_M460 8 /* Requires vendor init */ enum { U3G_BULK_WR, @@ -192,6 +196,7 @@ static const struct usb_device_id u3g_de U3G_DEV(ANYDATA, ADU_E100X, 0), U3G_DEV(AXESSTEL, DATAMODEM, 0), U3G_DEV(CMOTECH, CDMA_MODEM1, 0), + U3G_DEV(CMOTECH, CGU628, U3GINIT_CMOTECH), U3G_DEV(DELL, U5500, 0), U3G_DEV(DELL, U5505, 0), U3G_DEV(DELL, U5510, 0), @@ -211,73 +216,73 @@ static const struct usb_device_id u3g_de U3G_DEV(DLINK3, DWM652, 0), U3G_DEV(HP, EV2200, 0), U3G_DEV(HP, HS2300, 0), - U3G_DEV(HUAWEI, E1401, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1402, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1403, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1404, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1405, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1406, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1407, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1408, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1409, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E140A, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E140B, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E140D, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E140E, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E140F, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1410, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1411, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1412, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1413, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1414, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1415, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1416, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1417, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1418, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1419, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E141A, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E141B, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E141C, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E141D, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E141E, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E141F, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1420, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1421, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1422, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1423, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1424, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1425, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1426, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1427, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1428, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1429, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E142A, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E142B, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E142C, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E142D, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E142E, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E142F, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1430, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1431, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1432, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1433, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1434, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1435, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1436, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1437, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1438, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E1439, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E143A, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E143B, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E143C, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E143D, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E143E, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E143F, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E14AC, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E180V, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E220, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, E220BIS, U3GFL_HUAWEI_INIT), - U3G_DEV(HUAWEI, MOBILE, U3GFL_HUAWEI_INIT), + U3G_DEV(HUAWEI, E1401, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1402, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1403, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1404, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1405, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1406, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1407, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1408, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1409, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E140A, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E140B, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E140D, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E140E, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E140F, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1410, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1411, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1412, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1413, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1414, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1415, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1416, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1417, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1418, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1419, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E141A, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E141B, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E141C, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E141D, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E141E, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E141F, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1420, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1421, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1422, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1423, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1424, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1425, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1426, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1427, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1428, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1429, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E142A, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E142B, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E142C, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E142D, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E142E, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E142F, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1430, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1431, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1432, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1433, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1434, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1435, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1436, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1437, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1438, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E1439, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E143A, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E143B, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E143C, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E143D, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E143E, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E143F, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E14AC, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E180V, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI), + U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI), U3G_DEV(KYOCERA2, CDMA_MSM_K, 0), U3G_DEV(KYOCERA2, KPC680, 0), U3G_DEV(MERLIN, V620, 0), @@ -294,7 +299,7 @@ static const struct usb_device_id u3g_de U3G_DEV(NOVATEL, U727_2, 0), U3G_DEV(NOVATEL, U740, 0), U3G_DEV(NOVATEL, U740_2, 0), - U3G_DEV(NOVATEL, U760, U3GFL_SCSI_EJECT), + U3G_DEV(NOVATEL, U760, U3GINIT_SCSIEJECT), U3G_DEV(NOVATEL, U870, 0), U3G_DEV(NOVATEL, V620, 0), U3G_DEV(NOVATEL, V640, 0), @@ -338,7 +343,7 @@ static const struct usb_device_id u3g_de U3G_DEV(QUALCOMMINC, AC2726, 0), U3G_DEV(QUALCOMMINC, AC8700, 0), U3G_DEV(QUALCOMMINC, AC8710, 0), - U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GFL_SCSI_EJECT), + U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GINIT_SCSIEJECT), U3G_DEV(QUALCOMMINC, E0002, 0), U3G_DEV(QUALCOMMINC, E0003, 0), U3G_DEV(QUALCOMMINC, E0004, 0), @@ -405,7 +410,6 @@ static const struct usb_device_id u3g_de U3G_DEV(QUALCOMMINC, E2003, 0), U3G_DEV(QUALCOMMINC, MF626, 0), U3G_DEV(QUALCOMMINC, MF628, 0), - U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GFL_SCSI_EJECT), U3G_DEV(QUANTA, GKE, 0), U3G_DEV(QUANTA, GLE, 0), U3G_DEV(QUANTA, GLX, 0), @@ -466,7 +470,7 @@ static const struct usb_device_id u3g_de U3G_DEV(SIERRA, MINI5725, 0), U3G_DEV(SIERRA, T11, 0), U3G_DEV(SIERRA, T598, 0), - U3G_DEV(SILABS, SAEL, U3GFL_SAEL_M460_INIT), + U3G_DEV(SILABS, SAEL, U3GINIT_SAEL_M460), U3G_DEV(STELERA, C105, 0), U3G_DEV(STELERA, E1003, 0), U3G_DEV(STELERA, E1004, 0), @@ -492,12 +496,14 @@ static const struct usb_device_id u3g_de U3G_DEV(TOSHIBA, HSDPA, 0), U3G_DEV(YISO, C893, 0), /* Autoinstallers */ - U3G_DEV(NOVATEL, ZEROCD, U3GFL_SCSI_EJECT), - U3G_DEV(SIERRA, TRUINSTALL, U3GFL_SIERRA_INIT), + U3G_DEV(NOVATEL, ZEROCD, U3GINIT_SCSIEJECT), + U3G_DEV(OPTION, GTICON322, U3GINIT_REZERO), + U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GINIT_ZTESTOR), + U3G_DEV(SIERRA, TRUINSTALL, U3GINIT_SIERRA), #undef U3G_DEV }; -static void +static int u3g_sierra_init(struct usb_device *udev) { struct usb_device_request req; @@ -512,10 +518,10 @@ u3g_sierra_init(struct usb_device *udev) NULL, 0, NULL, USB_MS_HZ)) { /* ignore any errors */ } - return; + return (0); } -static void +static int u3g_huawei_init(struct usb_device *udev) { struct usb_device_request req; @@ -530,7 +536,7 @@ u3g_huawei_init(struct usb_device *udev) NULL, 0, NULL, USB_MS_HZ)) { /* ignore any errors */ } - return; + return (0); } static void @@ -625,7 +631,7 @@ u3g_test_autoinst(void *arg, struct usb_ { struct usb_interface *iface; struct usb_interface_descriptor *id; - uint32_t flags; + int error; if (uaa->dev_state != UAA_DEV_READY) return; @@ -636,25 +642,41 @@ u3g_test_autoinst(void *arg, struct usb_ id = iface->idesc; if (id == NULL || id->bInterfaceClass != UICLASS_MASS) return; - if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa)) { - /* no device match */ - return; - } - flags = USB_GET_DRIVER_INFO(uaa); + if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa)) + return; /* no device match */ - if (flags & U3GFL_HUAWEI_INIT) { - u3g_huawei_init(udev); - } else if (flags & U3GFL_SCSI_EJECT) { - if (usb_test_autoinstall(udev, 0, 1) != 0) - return; - } else if (flags & U3GFL_SIERRA_INIT) { - u3g_sierra_init(udev); - } else { - /* no quirks */ - return; + switch (USB_GET_DRIVER_INFO(uaa)) { + case U3GINIT_HUAWEI: + error = u3g_huawei_init(udev); + break; + case U3GINIT_SCSIEJECT: + error = usb_msc_eject(udev, 0, MSC_EJECT_STOPUNIT); + break; + case U3GINIT_REZERO: + error = usb_msc_eject(udev, 0, MSC_EJECT_REZERO); + break; + case U3GINIT_ZTESTOR: + error = usb_msc_eject(udev, 0, MSC_EJECT_ZTESTOR); + break; + case U3GINIT_CMOTECH: + error = usb_msc_eject(udev, 0, MSC_EJECT_CMOTECH); + break; + case U3GINIT_SIERRA: + error = u3g_sierra_init(udev); + break; + case U3GINIT_WAIT: + /* Just pretend we ejected, the card will timeout */ + error = 0; + break; + default: + /* no 3G eject quirks */ + error = EOPNOTSUPP; + break; + } + if (error == 0) { + /* success, mark the udev as disappearing */ + uaa->dev_state = UAA_DEV_EJECTING; } - uaa->dev_state = UAA_DEV_EJECTING; - return; /* success */ } static int @@ -701,15 +723,14 @@ u3g_attach(device_t dev) struct usb_interface *iface; struct usb_interface_descriptor *id; uint32_t iface_valid; - int error, flags, nports; + int error, type, nports; int ep, n; uint8_t i; DPRINTF("sc=%p\n", sc); - flags = USB_GET_DRIVER_INFO(uaa); - - if (flags & U3GFL_SAEL_M460_INIT) + type = USB_GET_DRIVER_INFO(uaa); + if (type == U3GINIT_SAEL_M460) u3g_sael_m460_init(uaa->device); /* copy in USB config */ @@ -781,8 +802,8 @@ u3g_attach(device_t dev) DPRINTF("ucom_attach failed\n"); goto detach; } - if (sc->sc_numports > 1) - device_printf(dev, "Found %u ports.\n", sc->sc_numports); + device_printf(dev, "Found %u port%s.\n", sc->sc_numports, + sc->sc_numports > 1 ? "s":""); return (0); detach: Modified: stable/8/sys/dev/usb/usb_device.c ============================================================================== --- stable/8/sys/dev/usb/usb_device.c Sun Jan 17 18:30:37 2010 (r202509) +++ stable/8/sys/dev/usb/usb_device.c Sun Jan 17 18:31:27 2010 (r202510) @@ -1805,7 +1805,7 @@ repeat_set_config: * Try to figure out if we have an * auto-install disk there: */ - if (usb_test_autoinstall(udev, 0, 0) == 0) { + if (usb_iface_is_cdrom(udev, 0)) { DPRINTFN(0, "Found possible auto-install " "disk (trying next config)\n"); config_index++; Modified: stable/8/sys/dev/usb/usb_msctest.c ============================================================================== --- stable/8/sys/dev/usb/usb_msctest.c Sun Jan 17 18:30:37 2010 (r202509) +++ stable/8/sys/dev/usb/usb_msctest.c Sun Jan 17 18:31:27 2010 (r202510) @@ -67,8 +67,7 @@ #include #include #include - -#include +#include enum { ST_COMMAND, @@ -86,7 +85,18 @@ enum { DIR_NONE, }; +#define SCSI_INQ_LEN 0x24 +static uint8_t scsi_test_unit_ready[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t scsi_inquiry[] = { 0x12, 0x00, 0x00, 0x00, SCSI_INQ_LEN, 0x00 }; +static uint8_t scsi_rezero_init[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t scsi_start_stop_unit[] = { 0x1b, 0x00, 0x00, 0x00, 0x02, 0x00 }; +static uint8_t scsi_ztestor_eject[] = { 0x85, 0x01, 0x01, 0x01, 0x18, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00 }; +static uint8_t scsi_cmotech_eject[] = { 0xff, 0x52, 0x44, 0x45, 0x56, 0x43, + 0x48, 0x47 }; + #define BULK_SIZE 64 /* dummy */ +#define ERR_CSW_FAILED -1 /* Command Block Wrapper */ struct bbb_cbw { @@ -134,8 +144,8 @@ struct bbb_transfer { uint8_t dir; uint8_t lun; uint8_t state; - uint8_t error; uint8_t status_try; + int error; uint8_t buffer[256]; }; @@ -147,6 +157,15 @@ static usb_callback_t bbb_data_write_cal static usb_callback_t bbb_data_wr_cs_callback; static usb_callback_t bbb_status_callback; +static void bbb_done(struct bbb_transfer *, int); +static void bbb_transfer_start(struct bbb_transfer *, uint8_t); +static void bbb_data_clear_stall_callback(struct usb_xfer *, uint8_t, + uint8_t); +static uint8_t bbb_command_start(struct bbb_transfer *, uint8_t, uint8_t, + void *, size_t, void *, size_t, usb_timeout_t); +static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t); +static void bbb_detach(struct bbb_transfer *); + static const struct usb_config bbb_config[ST_MAX] = { [ST_COMMAND] = { @@ -208,25 +227,9 @@ static const struct usb_config bbb_confi }; static void -bbb_done(struct bbb_transfer *sc, uint8_t error) +bbb_done(struct bbb_transfer *sc, int error) { - struct usb_xfer *xfer; - - xfer = sc->xfer[sc->state]; - - /* verify the error code */ - if (error) { - switch (USB_GET_STATE(xfer)) { - case USB_ST_SETUP: - case USB_ST_TRANSFERRED: - error = 1; - break; - default: - error = 2; - break; - } - } sc->error = error; sc->state = ST_COMMAND; sc->status_try = 1; @@ -253,7 +256,7 @@ bbb_data_clear_stall_callback(struct usb bbb_transfer_start(sc, next_xfer); break; default: - bbb_done(sc, 1); + bbb_done(sc, USB_ERR_STALLED); break; } } @@ -291,7 +294,7 @@ bbb_command_callback(struct usb_xfer *xf break; default: /* Error */ - bbb_done(sc, 1); + bbb_done(sc, error); break; } } @@ -333,7 +336,7 @@ bbb_data_read_callback(struct usb_xfer * default: /* Error */ if (error == USB_ERR_CANCELLED) { - bbb_done(sc, 1); + bbb_done(sc, error); } else { bbb_transfer_start(sc, ST_DATA_RD_CS); } @@ -385,7 +388,7 @@ bbb_data_write_callback(struct usb_xfer default: /* Error */ if (error == USB_ERR_CANCELLED) { - bbb_done(sc, 1); + bbb_done(sc, error); } else { bbb_transfer_start(sc, ST_DATA_WR_CS); } @@ -415,11 +418,11 @@ bbb_status_callback(struct usb_xfer *xfe /* very simple status check */ if (actlen < sizeof(sc->csw)) { - bbb_done(sc, 1);/* error */ + bbb_done(sc, USB_ERR_SHORT_XFER); } else if (sc->csw.bCSWStatus == CSWSTATUS_GOOD) { - bbb_done(sc, 0);/* success */ + bbb_done(sc, 0); /* success */ } else { - bbb_done(sc, 1);/* error */ + bbb_done(sc, ERR_CSW_FAILED); /* error */ } break; @@ -429,11 +432,11 @@ bbb_status_callback(struct usb_xfer *xfe break; default: - DPRINTFN(0, "Failed to read CSW: %s, try %d\n", + DPRINTF("Failed to read CSW: %s, try %d\n", usbd_errstr(error), sc->status_try); if (error == USB_ERR_CANCELLED || sc->status_try) { - bbb_done(sc, 1); + bbb_done(sc, error); } else { sc->status_try = 1; bbb_transfer_start(sc, ST_DATA_RD_CS); @@ -451,7 +454,7 @@ bbb_status_callback(struct usb_xfer *xfe *------------------------------------------------------------------------*/ static uint8_t bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun, - void *data_ptr, usb_size_t data_len, uint8_t cmd_len, + void *data_ptr, size_t data_len, void *cmd_ptr, size_t cmd_len, usb_timeout_t data_timeout) { sc->lun = lun; @@ -461,54 +464,46 @@ bbb_command_start(struct bbb_transfer *s sc->data_rem = data_len; sc->data_timeout = (data_timeout + USB_MS_HZ); sc->actlen = 0; + sc->data_ptr = data_ptr; sc->cmd_len = cmd_len; + bzero(&sc->cbw.CBWCDB, sizeof(sc->cbw.CBWCDB)); + bcopy(cmd_ptr, &sc->cbw.CBWCDB, cmd_len); + DPRINTFN(1, "SCSI cmd = %*D\n", cmd_len, &sc->cbw.CBWCDB, ":"); + mtx_lock(&sc->mtx); usbd_transfer_start(sc->xfer[sc->state]); while (usbd_transfer_pending(sc->xfer[sc->state])) { cv_wait(&sc->cv, &sc->mtx); } + mtx_unlock(&sc->mtx); return (sc->error); } -/*------------------------------------------------------------------------* - * usb_test_autoinstall - * - * Return values: - * 0: This interface is an auto install disk (CD-ROM) - * Else: Not an auto install disk. - *------------------------------------------------------------------------*/ -usb_error_t -usb_test_autoinstall(struct usb_device *udev, uint8_t iface_index, - uint8_t do_eject) +static struct bbb_transfer * +bbb_attach(struct usb_device *udev, uint8_t iface_index) { struct usb_interface *iface; struct usb_interface_descriptor *id; - usb_error_t err; - uint8_t timeout; - uint8_t sid_type; struct bbb_transfer *sc; + usb_error_t err; - if (udev == NULL) { - return (USB_ERR_INVAL); - } iface = usbd_get_iface(udev, iface_index); - if (iface == NULL) { - return (USB_ERR_INVAL); - } + if (iface == NULL) + return (NULL); + id = iface->idesc; - if (id == NULL) { - return (USB_ERR_INVAL); - } - if (id->bInterfaceClass != UICLASS_MASS) { - return (USB_ERR_INVAL); - } + if (id == NULL || id->bInterfaceClass != UICLASS_MASS) + return (NULL); + switch (id->bInterfaceSubClass) { case UISUBCLASS_SCSI: case UISUBCLASS_UFI: + case UISUBCLASS_SFF8020I: + case UISUBCLASS_SFF8070I: break; default: - return (USB_ERR_INVAL); + return (NULL); } switch (id->bInterfaceProtocol) { @@ -516,75 +511,112 @@ usb_test_autoinstall(struct usb_device * case UIPROTO_MASS_BBB: break; default: - return (USB_ERR_INVAL); + return (NULL); } sc = malloc(sizeof(*sc), M_USB, M_WAITOK | M_ZERO); - if (sc == NULL) { - return (USB_ERR_NOMEM); - } mtx_init(&sc->mtx, "USB autoinstall", NULL, MTX_DEF); cv_init(&sc->cv, "WBBB"); - err = usbd_transfer_setup(udev, - &iface_index, sc->xfer, bbb_config, + err = usbd_transfer_setup(udev, &iface_index, sc->xfer, bbb_config, ST_MAX, sc, &sc->mtx); - if (err) { - goto done; + bbb_detach(sc); + return (NULL); } - mtx_lock(&sc->mtx); - - timeout = 4; /* tries */ - -repeat_inquiry: - - sc->cbw.CBWCDB[0] = 0x12; /* INQUIRY */ - sc->cbw.CBWCDB[1] = 0; - sc->cbw.CBWCDB[2] = 0; - sc->cbw.CBWCDB[3] = 0; - sc->cbw.CBWCDB[4] = 0x24; /* length */ - sc->cbw.CBWCDB[5] = 0; - err = bbb_command_start(sc, DIR_IN, 0, - sc->buffer, 0x24, 6, USB_MS_HZ); - - if ((sc->actlen != 0) && (err == 0)) { - sid_type = sc->buffer[0] & 0x1F; - if (sid_type == 0x05) { - /* CD-ROM */ - if (do_eject) { - /* 0: opcode: SCSI START/STOP */ - sc->cbw.CBWCDB[0] = 0x1b; - /* 1: byte2: Not immediate */ - sc->cbw.CBWCDB[1] = 0x00; - /* 2..3: reserved */ - sc->cbw.CBWCDB[2] = 0x00; - sc->cbw.CBWCDB[3] = 0x00; - /* 4: Load/Eject command */ - sc->cbw.CBWCDB[4] = 0x02; - /* 5: control */ - sc->cbw.CBWCDB[5] = 0x00; - err = bbb_command_start(sc, DIR_OUT, 0, - NULL, 0, 6, USB_MS_HZ); - - DPRINTFN(0, "Eject CD command " - "status: %s\n", usbd_errstr(err)); - } - err = 0; - goto done; - } - } else if ((err != 2) && --timeout) { - usb_pause_mtx(&sc->mtx, hz); - goto repeat_inquiry; - } - err = USB_ERR_INVAL; - goto done; + return (sc); +} -done: - mtx_unlock(&sc->mtx); +static void +bbb_detach(struct bbb_transfer *sc) +{ usbd_transfer_unsetup(sc->xfer, ST_MAX); mtx_destroy(&sc->mtx); cv_destroy(&sc->cv); free(sc, M_USB); - return (err); +} + +/*------------------------------------------------------------------------* + * usb_iface_is_cdrom + * + * Return values: + * 1: This interface is an auto install disk (CD-ROM) + * 0: Not an auto install disk. + *------------------------------------------------------------------------*/ +int +usb_iface_is_cdrom(struct usb_device *udev, uint8_t iface_index) +{ + struct bbb_transfer *sc; + usb_error_t err; + uint8_t timeout, is_cdrom; + uint8_t sid_type; + + sc = bbb_attach(udev, iface_index); + if (sc == NULL) + return (0); + + is_cdrom = 0; + timeout = 4; /* tries */ + while (--timeout) { + err = bbb_command_start(sc, DIR_IN, 0, sc->buffer, + SCSI_INQ_LEN, &scsi_inquiry, sizeof(scsi_inquiry), + USB_MS_HZ); + + if (err == 0 && sc->actlen > 0) { + sid_type = sc->buffer[0] & 0x1F; + if (sid_type == 0x05) + is_cdrom = 1; + break; + } else if (err != ERR_CSW_FAILED) + break; /* non retryable error */ + usb_pause_mtx(NULL, hz); + } + bbb_detach(sc); + return (is_cdrom); +} + +usb_error_t +usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method) +{ + struct bbb_transfer *sc; + usb_error_t err; + + sc = bbb_attach(udev, iface_index); + if (sc == NULL) + return (USB_ERR_INVAL); + + err = 0; + switch (method) { + case MSC_EJECT_STOPUNIT: + err = bbb_command_start(sc, DIR_IN, 0, NULL, 0, + &scsi_test_unit_ready, sizeof(scsi_test_unit_ready), + USB_MS_HZ); + DPRINTF("Test unit ready status: %s\n", usbd_errstr(err)); + err = bbb_command_start(sc, DIR_IN, 0, NULL, 0, + &scsi_start_stop_unit, sizeof(scsi_start_stop_unit), + USB_MS_HZ); + break; + case MSC_EJECT_REZERO: + err = bbb_command_start(sc, DIR_IN, 0, NULL, 0, + &scsi_rezero_init, sizeof(scsi_rezero_init), + USB_MS_HZ); + break; + case MSC_EJECT_ZTESTOR: + err = bbb_command_start(sc, DIR_IN, 0, NULL, 0, + &scsi_ztestor_eject, sizeof(scsi_ztestor_eject), + USB_MS_HZ); + break; + case MSC_EJECT_CMOTECH: + err = bbb_command_start(sc, DIR_IN, 0, NULL, 0, + &scsi_cmotech_eject, sizeof(scsi_cmotech_eject), + USB_MS_HZ); + break; + default: + printf("usb_msc_eject: unknown eject method (%d)\n", method); + break; + } + DPRINTF("Eject CD command status: %s\n", usbd_errstr(err)); + + bbb_detach(sc); + return (0); } Modified: stable/8/sys/dev/usb/usb_msctest.h ============================================================================== --- stable/8/sys/dev/usb/usb_msctest.h Sun Jan 17 18:30:37 2010 (r202509) +++ stable/8/sys/dev/usb/usb_msctest.h Sun Jan 17 18:31:27 2010 (r202510) @@ -27,7 +27,16 @@ #ifndef _USB_MSCTEST_H_ #define _USB_MSCTEST_H_ -usb_error_t usb_test_autoinstall(struct usb_device *udev, - uint8_t iface_index, uint8_t do_eject); +enum { + MSC_EJECT_STOPUNIT, + MSC_EJECT_REZERO, + MSC_EJECT_ZTESTOR, + MSC_EJECT_CMOTECH +}; + +int usb_iface_is_cdrom(struct usb_device *udev, + uint8_t iface_index); +usb_error_t usb_msc_eject(struct usb_device *udev, + uint8_t iface_index, int method); #endif /* _USB_MSCTEST_H_ */