Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Jan 2010 18:31:27 +0000 (UTC)
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r202510 - in stable/8/sys/dev/usb: . serial
Message-ID:  <201001171831.o0HIVRwC009686@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <dev/usb/usb_device.h>
 #include <dev/usb/usb_request.h>
 #include <dev/usb/usb_util.h>
-
-#include <dev/usb/usb.h>
+#include <dev/usb/quirk/usb_quirk.h>
 
 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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001171831.o0HIVRwC009686>