public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Pete Zaitcev <zaitcev@redhat.com>
To: <marcelo.tosatti@cyclades.com>
Cc: zaitcev@redhat.com, linux-kernel@vger.kernel.org
Subject: USB 2.4.30: hid for ia64
Date: Thu, 10 Feb 2005 16:01:49 -0800	[thread overview]
Message-ID: <20050210160149.12a56e18@localhost.localdomain> (raw)

Apparently, the HP rx5670 fails to reboot if a USB keyboard if attached
without this patch (and the OHCI fix we accepted for 2.4.29).

This bug is better known for its effect on Altix, but SGI ships a magic
kernel anyhow, so I don't want to use that as justification.

The original patch comes from Jes Sorensen, but then I corrupted his
idea with my simplifications and a partial backport from 2.6, so if this
fails do not e-mail him.

diff -urpN -X dontdiff linux-2.4.30-pre1/drivers/usb/hid-core.c linux-2.4.30-pre1-usb/drivers/usb/hid-core.c
--- linux-2.4.30-pre1/drivers/usb/hid-core.c	2004-11-22 23:04:18.000000000 -0800
+++ linux-2.4.30-pre1-usb/drivers/usb/hid-core.c	2005-02-10 11:18:08.000000000 -0800
@@ -1064,18 +1064,31 @@ static int hid_submit_out(struct hid_dev
 static void hid_ctrl(struct urb *urb)
 {
 	struct hid_device *hid = urb->context;
+	unsigned long flags;
 
 	if (urb->status)
 		warn("ctrl urb status %d received", urb->status);
 
+	spin_lock_irqsave(&hid->outlock, flags);
+
 	hid->outtail = (hid->outtail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
 
-	if (hid->outhead != hid->outtail)
-		hid_submit_out(hid);
+	if (hid->outhead != hid->outtail) {
+		if (hid_submit_out(hid)) {
+			clear_bit(HID_OUT_RUNNING, &hid->iofl);
+		}
+		spin_unlock_irqrestore(&hid->outlock, flags);
+		return;
+	}
+
+	clear_bit(HID_OUT_RUNNING, &hid->iofl);
+	spin_unlock_irqrestore(&hid->outlock, flags);
 }
 
 void hid_write_report(struct hid_device *hid, struct hid_report *report)
 {
+	unsigned long flags;
+
 	if (hid->report_enum[report->type].numbered) {
 		hid->out[hid->outhead].buffer[0] = report->id;
 		hid_output_report(report, hid->out[hid->outhead].buffer + 1);
@@ -1087,13 +1100,18 @@ void hid_write_report(struct hid_device 
 
 	hid->out[hid->outhead].dr.wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
 
+	spin_lock_irqsave(&hid->outlock, flags);
+
 	hid->outhead = (hid->outhead + 1) & (HID_CONTROL_FIFO_SIZE - 1);
 
 	if (hid->outhead == hid->outtail)
 		hid->outtail = (hid->outtail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
 
-	if (hid->urbout.status != -EINPROGRESS)
-		hid_submit_out(hid);
+	if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl))
+		if (hid_submit_out(hid))
+			clear_bit(HID_OUT_RUNNING, &hid->iofl);
+
+	spin_unlock_irqrestore(&hid->outlock, flags);
 }
 
 int hid_open(struct hid_device *hid)
@@ -1333,6 +1351,8 @@ static struct hid_device *usb_hid_config
 		return NULL;
 	}
 
+	spin_lock_init(&hid->outlock);
+
 	hid->version = hdesc->bcdHID;
 	hid->country = hdesc->bCountryCode;
 	hid->dev = dev;
diff -urpN -X dontdiff linux-2.4.30-pre1/drivers/usb/hid.h linux-2.4.30-pre1-usb/drivers/usb/hid.h
--- linux-2.4.30-pre1/drivers/usb/hid.h	2005-01-26 13:04:23.000000000 -0800
+++ linux-2.4.30-pre1-usb/drivers/usb/hid.h	2005-02-10 11:26:43.000000000 -0800
@@ -302,6 +302,8 @@ struct hid_control_fifo {
 #define HID_CLAIMED_INPUT	1
 #define HID_CLAIMED_HIDDEV	2
 
+#define HID_OUT_RUNNING		2
+
 struct hid_input {
 	struct list_head list;
 	struct hid_report *report;
@@ -322,12 +324,15 @@ struct hid_device {							/* device repo
 	struct usb_device *dev;						/* USB device */
 	int ifnum;							/* USB interface number */
 
+	unsigned long iofl;						/* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
+
 	struct urb urb;							/* USB URB structure */
 	char buffer[HID_BUFFER_SIZE];					/* Rx buffer */
 
 	struct urb urbout;						/* Output URB */
 	struct hid_control_fifo out[HID_CONTROL_FIFO_SIZE];		/* Transmit buffer */
 	unsigned char outhead, outtail;					/* Tx buffer head & tail */
+	spinlock_t outlock;						/* Output fifo spinlock */
 
 	unsigned claimed;						/* Claimed by hidinput, hiddev? */	
 	unsigned quirks;						/* Various quirks the device can pull on us */

                 reply	other threads:[~2005-02-11  0:01 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050210160149.12a56e18@localhost.localdomain \
    --to=zaitcev@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo.tosatti@cyclades.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox