changeset 918:bf7120aa2e89

4644326 scsa2usb goes into a loop while processing STALL condition 6261946 usbser_edge: NULL pointer dereference panic in edge_pipe_start_polling 6308155 comments confusing in scsa2usb.conf 6316748 panic: assertion failed: rval == DDI_SUCCESS, file: common/io/usb/hcd/openhci/ohci.c (1998) 6328230 logitech mx900 mouse does not enumerate on uhci 6338046 Sun Type 6 Japanese keyboard and other Japanese keyboards should be recognized 6347166 free(char *) is not correct in cfga_configfile.c
author qz150045
date Mon, 14 Nov 2005 22:12:11 -0800
parents a3d1e8247fa0
children 3e2e8347d278
files usr/src/cmd/loadkeys/type_6/Makefile usr/src/lib/cfgadm_plugins/usb/common/cfga_configfile.c usr/src/pkgdefs/SUNWkey/prototype_com usr/src/uts/common/io/usb/clients/hid/hid.c usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c usr/src/uts/common/io/usb/hcd/openhci/ohci.c usr/src/uts/common/io/usb/hcd/uhci/uhciutil.c usr/src/uts/common/io/usb/scsa2usb/scsa2usb.conf usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c usr/src/uts/common/sys/usb/clients/hid/hid.h usr/src/uts/common/sys/usb/clients/usbkbm/usbkbm.h usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h
diffstat 12 files changed, 204 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/loadkeys/type_6/Makefile	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/cmd/loadkeys/type_6/Makefile	Mon Nov 14 22:12:11 2005 -0800
@@ -49,7 +49,7 @@
         layout_0f layout_10 layout_12 layout_13 layout_16 layout_19 \
         layout_1a layout_1b layout_1c layout_1e layout_20 layout_21 \
         layout_100 layout_18 layout_101 layout_102 layout_103 layout_104 \
-        layout_105 layout_106 layout_107 layout_108
+        layout_105 layout_106 layout_107 layout_108 layout_10f
 
 ROOTLINKS= $(LAYOUTS:%=$(ROOTKEYDIR)/%)
 
@@ -157,6 +157,9 @@
 	$(RM) $@; $(LN) $(ROOTKEYDIR)/maltauk  $@
 
 $(ROOTKEYDIR)/layout_108: $(ROOTKEYDIR)/albania
-	$(RM) $@; $(LN) $(ROOTKEYDIR)/albania  $@ 
+	$(RM) $@; $(LN) $(ROOTKEYDIR)/albania  $@
+
+$(ROOTKEYDIR)/layout_10f: $(ROOTKEYDIR)/japan
+	$(RM) $@; $(LN) $(ROOTKEYDIR)/japan $@ 
 
 include ../../Makefile.targ
--- a/usr/src/lib/cfgadm_plugins/usb/common/cfga_configfile.c	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/lib/cfgadm_plugins/usb/common/cfga_configfile.c	Mon Nov 14 22:12:11 2005 -0800
@@ -558,7 +558,7 @@
 						break;
 					default:
 						parse_state = USB_ERROR;
-						free((char *)(uintptr_t)llptr);
+						free((void *)(uintptr_t)llptr);
 					}
 				} else {
 					parse_state = USB_ERROR;
--- a/usr/src/pkgdefs/SUNWkey/prototype_com	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/pkgdefs/SUNWkey/prototype_com	Mon Nov 14 22:12:11 2005 -0800
@@ -162,3 +162,4 @@
 l none usr/share/lib/keytables/type_6/layout_106=../../../../../usr/share/lib/keytables/type_6/maltaus
 l none usr/share/lib/keytables/type_6/layout_107=../../../../../usr/share/lib/keytables/type_6/maltauk
 l none usr/share/lib/keytables/type_6/layout_108=../../../../../usr/share/lib/keytables/type_6/albania
+l none usr/share/lib/keytables/type_6/layout_10f=../../../../../usr/share/lib/keytables/type_6/japan
--- a/usr/src/uts/common/io/usb/clients/hid/hid.c	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/uts/common/io/usb/clients/hid/hid.c	Mon Nov 14 22:12:11 2005 -0800
@@ -2085,6 +2085,7 @@
 	uchar_t		request_type;
 	hid_req_t	*hid_req_data = NULL;
 	hid_polled_input_callback_t hid_polled_input;
+	hid_vid_pid_t	hid_vid_pid;
 
 	USB_DPRINTF_L4(PRINT_MASK_ALL, hidp->hid_log_handle,
 	    "hid_mctl_receive");
@@ -2134,6 +2135,35 @@
 			/* retry */
 			return (HID_ENQUEUE);
 		}
+	case HID_GET_VID_PID:
+		if (canputnext(RD(q))) {
+			freemsg(mp->b_cont);
+
+			hid_vid_pid.VendorId =
+				hidp->hid_dev_descr->idVendor;
+			hid_vid_pid.ProductId =
+				hidp->hid_dev_descr->idProduct;
+
+			mp->b_cont = hid_data2mblk(
+			    (uchar_t *)&hid_vid_pid, sizeof (hid_vid_pid_t));
+			if (mp->b_cont == NULL) {
+				/*
+				 * can't allocate mblk, indicate that nothing
+				 * is being returned.
+				 */
+				iocp->ioc_count = 0;
+			} else {
+				iocp->ioc_count =
+				    sizeof (hid_vid_pid_t);
+			}
+			qreply(q, mp);
+
+			return (HID_SUCCESS);
+		} else {
+
+			/* retry */
+			return (HID_ENQUEUE);
+		}
 	case HID_OPEN_POLLED_INPUT:
 		if (canputnext(RD(q))) {
 			freemsg(mp->b_cont);
--- a/usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c	Mon Nov 14 22:12:11 2005 -0800
@@ -80,6 +80,7 @@
 static void	usbkbm_usb2pc_xlate(usbkbm_state_t *, int, enum keystate);
 static void	usbkbm_wrap_kbtrans(usbkbm_state_t *, int, enum keystate);
 static int 	usbkbm_set_protocol(usbkbm_state_t *, uint16_t);
+static int 	usbkbm_get_vid_pid(usbkbm_state_t *);
 
 /* stream qinit functions defined here */
 static int	usbkbm_open(queue_t *, dev_t *, int, int, cred_t *);
@@ -116,7 +117,7 @@
 static uchar_t  usbkbm_led_state = 0;
 
 /* This variable saves the layout state */
-static uchar_t usbkbm_layout = 0;
+static uint16_t usbkbm_layout = 0;
 
 /*
  * Function pointer array for mapping of scancodes.
@@ -573,6 +574,30 @@
 				USB_KBD_DEFAULT_PACKET_SIZE;
 	}
 
+	/*
+	 * Although Sun Japanese type6 and type7 keyboards have the same
+	 * layout number(15), they should be recognized for loading the
+	 * different keytables on upper apps (e.g. X). The new layout
+	 * number (271) is defined for the Sun Japanese type6 keyboards.
+	 * The layout number (15) specified in HID spec is used for other
+	 * Japanese keyboards. It is a workaround for the old Sun Japanese
+	 * type6 keyboards defect.
+	 */
+	if (usbkbmd->usbkbm_layout == SUN_JAPANESE_TYPE7) {
+
+		if ((ret = usbkbm_get_vid_pid(usbkbmd)) != 0) {
+
+			return (ret);
+		}
+
+		if ((usbkbmd->usbkbm_vid_pid.VendorId ==
+			HID_SUN_JAPANESE_TYPE6_KBD_VID) &&
+			(usbkbmd->usbkbm_vid_pid.ProductId ==
+			HID_SUN_JAPANESE_TYPE6_KBD_PID)) {
+			usbkbmd->usbkbm_layout = SUN_JAPANESE_TYPE6;
+		}
+	}
+
 	kbtrans_streams_set_keyboard(usbkbmd->usbkbm_kbtrans, KB_USB,
 					usbkbm_keyindex);
 
@@ -1131,6 +1156,17 @@
 		usbkbmd->usbkbm_flags &= ~USBKBM_QWAIT;
 
 		break;
+	case HID_GET_VID_PID:
+		if ((data != NULL) &&
+		    (iocp->ioc_count == sizeof (hid_vid_pid_t)) &&
+		    ((mp->b_cont->b_wptr - mp->b_cont->b_rptr) ==
+		    iocp->ioc_count)) {
+			bcopy(data, &usbkbmd->usbkbm_vid_pid, iocp->ioc_count);
+		}
+		freemsg(mp);
+		usbkbmd->usbkbm_flags &= ~USBKBM_QWAIT;
+
+		break;
 	case HID_OPEN_POLLED_INPUT:
 		USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
 			"usbkbm_mctl_receive HID_OPEN_POLLED_INPUT");
@@ -1909,3 +1945,43 @@
 
 	return (0);
 }
+
+
+/*
+ * usbkbm_get_vid_pid
+ *	Issue a M_CTL to hid to get the device info
+ */
+static int
+usbkbm_get_vid_pid(usbkbm_state_t *usbkbmd)
+{
+	struct iocblk mctlmsg;
+	mblk_t *mctl_ptr;
+	queue_t *q = usbkbmd->usbkbm_readq;
+
+	mctlmsg.ioc_cmd = HID_GET_VID_PID;
+	mctlmsg.ioc_count = 0;
+
+	mctl_ptr = usba_mk_mctl(mctlmsg, NULL, 0);
+	if (mctl_ptr == NULL) {
+		(void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
+		qprocsoff(q);
+		kmem_free(usbkbmd, sizeof (usbkbm_state_t));
+
+		return (ENOMEM);
+	}
+
+	putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
+	usbkbmd->usbkbm_flags |= USBKBM_QWAIT;
+	while (usbkbmd->usbkbm_flags & USBKBM_QWAIT) {
+		if (qwait_sig(q) == 0) {
+			usbkbmd->usbkbm_flags = 0;
+			(void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
+			qprocsoff(q);
+			kmem_free(usbkbmd, sizeof (usbkbm_state_t));
+
+			return (EINTR);
+		}
+	}
+
+	return (0);
+}
--- a/usr/src/uts/common/io/usb/hcd/openhci/ohci.c	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/uts/common/io/usb/hcd/openhci/ohci.c	Mon Nov 14 22:12:11 2005 -0800
@@ -1529,11 +1529,6 @@
 
 	bzero((void *)ohcip->ohci_hccap, real_length);
 
-	/*
-	 * DMA addresses for HCCA are bound
-	 */
-	ohcip->ohci_dma_addr_bind_flag |= OHCI_HCCA_DMA_BOUND;
-
 	/* Figure out the alignment requirements */
 	Set_OpReg(hcr_HCCA, 0xFFFFFFFF);
 
@@ -1591,6 +1586,11 @@
 		return (DDI_FAILURE);
 	}
 
+	/*
+	 * DMA addresses for HCCA are bound
+	 */
+	ohcip->ohci_dma_addr_bind_flag |= OHCI_HCCA_DMA_BOUND;
+
 	USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
 	    "ohci_init_hcca: physical 0x%p",
 	    (void *)(uintptr_t)ohcip->ohci_hcca_cookie.dmac_address);
--- a/usr/src/uts/common/io/usb/hcd/uhci/uhciutil.c	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/uts/common/io/usb/hcd/uhci/uhciutil.c	Mon Nov 14 22:12:11 2005 -0800
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1524,27 +1524,18 @@
 		length = req->intr_len;
 	} else {
 		ASSERT(pipe_dir == USB_EP_DIR_IN);
-		length = ((usb_intr_req_t *)pp->pp_client_periodic_in_reqp)->
-								intr_len;
+		length = (pp->pp_client_periodic_in_reqp) ?
+		    (((usb_intr_req_t *)pp->
+		    pp_client_periodic_in_reqp)->intr_len) :
+		    ph->p_ep.wMaxPacketSize;
 	}
 
-	if (pipe_dir == USB_EP_DIR_IN) {
-
-		/* For IN xfer, the length shouldn't exceed wMaxPacketSize. */
-		if (length > ph->p_ep.wMaxPacketSize) {
-
-			USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
-			    "uhci_insert_intr_td: Intr in req size 0x%lx is "
-			    "more than 0x%x", length, ph->p_ep.wMaxPacketSize);
-
-			return (USB_INVALID_REQUEST);
-		}
-
-	} else if (length > UHCI_MAX_TD_XFER_SIZE) {
-
-		/* For Out xfer, the length shouldn't exceed 8K */
+	/* Check the size of interrupt request */
+	if (length > UHCI_MAX_TD_XFER_SIZE) {
+
+		/* the length shouldn't exceed 8K */
 		USB_DPRINTF_L2(PRINT_MASK_LISTS, uhcip->uhci_log_hdl,
-		    "uhci_insert_intr_td: Intr out req size 0x%lx is "
+		    "uhci_insert_intr_td: Intr request size 0x%lx is "
 		    "more than 0x%x", length, UHCI_MAX_TD_XFER_SIZE);
 
 	    return (USB_INVALID_REQUEST);
--- a/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.conf	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/uts/common/io/usb/scsa2usb/scsa2usb.conf	Mon Nov 14 22:12:11 2005 -0800
@@ -86,14 +86,32 @@
 #		If this is the case, the device should have power
 #		management disabled by setting this to "off".
 # 
-#	remvalue - "false" if the device's hardware "removable"
-#		status is not to be ignored. This is the only legal
-#		value for this parameter. Normally all USB devices
-#		are considered removable devices, which allows them
-#		to be mounted by the Volume Management daemon.
-#		For some USB hard drives it may be desirable not to
-#		ignore their hardware removable status.
-# 
+#	remvalue - "false" if the device's removable media information
+#		in its hardware inquiry data is not to be ignored. This
+#		is the only legal value for this parameter. There is a
+#		removable media status bit in the USB storage device's
+#		inquiry data to indicate if the device has a media that
+#		can be removed. Usually only devices like floppy drives
+#		or CD/DVD drives that really have a removable media can
+#		have this bit set and be called removable media devices.
+#		Solaris treats removable media devices and non-
+#		removable media devices differently. Refer to "System
+#		Administration Guide: Devices and File Systems" -
+#		"Using USB Devices (Tasks)" - "Using USB Mass Storage
+#		Devices" section for the differences in system behavior
+#		of treating removable media devices and non-removable
+#		media devices.
+#
+#		By default, Solaris will treat all USB storage devices
+#		as removable media devices irrespective of the removable
+#		media bit value. The advantage is a consistent user
+#		experience. In some cases this may be undesirable and
+#		the removable media bit value should not be ignored. By
+#		setting "remvalue" to "false", the information provided
+#		by the device is preserved. Consequently a USB hard disk
+#		is treated as a real hard disk and will show in
+#		format(1M) disk list and no longer in rmformat(1M) list.
+#
 #	modesensevalue - "false" if the device cannot handle mode sense
 #		requests. This is the only legal value for this
 #		parameter. Some devices choke on mode sense requests
--- a/usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/uts/common/io/usb/scsa2usb/usb_ms_bulkonly.c	Mon Nov 14 22:12:11 2005 -0800
@@ -197,6 +197,7 @@
 scsa2usb_bulk_only_transport(scsa2usb_state_t *scsa2usbp, scsa2usb_cmd_t *cmd)
 {
 	int	rval;
+	int	nretry;
 	usb_bulk_req_t *req;
 
 	ASSERT(mutex_owned(&scsa2usbp->scsa2usb_mutex));
@@ -286,24 +287,31 @@
 	 * Start status phase
 	 * read in CSW
 	 */
-	if ((rval = scsa2usb_handle_status_start(scsa2usbp, req)) ==
-	    USB_SUCCESS) {
+	for (nretry = 0; nretry < SCSA2USB_STATUS_RETRIES; nretry++) {
+		rval = scsa2usb_handle_status_start(scsa2usbp, req);
+
+		if ((rval != USB_SUCCESS) &&
+		    (req->bulk_completion_reason == USB_CR_STALL)) {
+			/*
+			 * We ran into STALL condition here.
+			 * If the condition cannot be cleared
+			 * successfully, retry for limited times.
+			 */
+			scsa2usbp->scsa2usb_pkt_state =
+				    SCSA2USB_PKT_PROCESS_CSW;
+		} else {
+
+			break;
+		}
+	}
+
+	if (rval == USB_SUCCESS) {
 		/* process CSW */
 		rval = scsa2usb_handle_csw_result(scsa2usbp, req->bulk_data);
 	} else {
-		/*
-		 * we ran into an error, check if it was a STALL
-		 */
-		if (req->bulk_completion_reason == USB_CR_STALL)  {
-			scsa2usbp->scsa2usb_pkt_state =
-					SCSA2USB_PKT_PROCESS_CSW;
+		scsa2usb_bulk_only_handle_error(scsa2usbp, req);
 
-			goto Status_Phase;
-		} else {
-			scsa2usb_bulk_only_handle_error(scsa2usbp, req);
-
-			return (TRAN_FATAL_ERROR);
-		}
+		return (TRAN_FATAL_ERROR);
 	}
 
 	SCSA2USB_FREE_BULK_REQ(req);	/* free request */
--- a/usr/src/uts/common/sys/usb/clients/hid/hid.h	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/uts/common/sys/usb/clients/hid/hid.h	Mon Nov 14 22:12:11 2005 -0800
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -67,6 +67,14 @@
 } usb_hid_descr_t;
 
 /*
+ * Hid device information
+ */
+typedef struct hid_vid_pid {
+	uint16_t	VendorId;		/* vendor ID */
+	uint16_t	ProductId;		/* product ID */
+} hid_vid_pid_t;
+
+/*
  * Hid will turn the M_CTL request into a request control request on the
  * default pipe.  Hid needs the following information in the hid_req_t
  * structure.  See the details below for specific values for each command.
@@ -114,6 +122,11 @@
 #define	HID_GET_PARSER_HANDLE	0x0100		/* obtain parser handle */
 
 /*
+ * The M_CTL command is to get the device vendor ID and product ID.
+ */
+#define	HID_GET_VID_PID		0x0200		/* obtain device info */
+
+/*
  * M_CTL commands for event notifications
  */
 #define	HID_POWER_OFF		0x00DC
--- a/usr/src/uts/common/sys/usb/clients/usbkbm/usbkbm.h	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/uts/common/sys/usb/clients/usbkbm/usbkbm.h	Mon Nov 14 22:12:11 2005 -0800
@@ -144,6 +144,9 @@
 
 	int			usbkbm_vkbd_type;
 
+	/* keyboard device info from hid */
+	hid_vid_pid_t		usbkbm_vid_pid;
+
 	/* These entries are for polled input */
 	uint_t		usbkbm_polled_buffer_num_characters;
 	poll_keystate_t	usbkbm_polled_scancode_buffer[USB_POLLED_BUFFER_SIZE];
@@ -155,6 +158,13 @@
 #define	USB_PRESSED	0x00	/* key was pressed */
 #define	USB_RELEASED	0x01	/* key was released */
 
+/* Sun Japanese type6 and type7 keyboards layout numbers, vid and pid */
+#define	SUN_JAPANESE_TYPE6		271
+#define	SUN_JAPANESE_TYPE7		15
+#define	HID_SUN_JAPANESE_TYPE6_KBD_VID	0x0430
+#define	HID_SUN_JAPANESE_TYPE6_KBD_PID	0x0005
+
+
 /* Number of entries in the keytable */
 #define	KEYMAP_SIZE_USB		255
 
--- a/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h	Mon Nov 14 22:03:14 2005 -0800
+++ b/usr/src/uts/common/sys/usb/scsa2usb/scsa2usb.h	Mon Nov 14 22:12:11 2005 -0800
@@ -499,6 +499,9 @@
 /* drain timeout in seconds on the work thread */
 #define	SCSA2USB_DRAIN_TIMEOUT		60
 
+/* scsa2usb pkt xfer status phase retry times */
+#define	SCSA2USB_STATUS_RETRIES		3
+
 /*
  * limit on the number of requests that can be queued per LUN:
  * 3 for untagged queueing, 1 for scsiwatch and a margin of 2