--- kernel-source-2.4.21/drivers/usb/printer.c.get-id-lockup	2002-11-29 02:53:14 +0300
+++ kernel-source-2.4.21/drivers/usb/printer.c	2003-08-24 22:41:39 +0400
@@ -181,6 +181,7 @@
 
 #define USBLP_QUIRK_BIDIR	0x1	/* reports bidir but requires unidirectional mode (no INs/reads) */
 #define USBLP_QUIRK_USB_INIT	0x2	/* needs vendor USB init string */
+#define USBLP_QUIRK_GET_ID	0x4	/* locks up on parallel GET_ID and bulk I/O */
 
 static struct quirk_printer_struct quirk_printers[] = {
 	{ 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
@@ -191,6 +192,7 @@
 	{ 0x03f0, 0x0504, USBLP_QUIRK_BIDIR }, /* HP DeskJet 885C */
 	{ 0x03f0, 0x0604, USBLP_QUIRK_BIDIR }, /* HP DeskJet 840C */   
 	{ 0x03f0, 0x0804, USBLP_QUIRK_BIDIR }, /* HP DeskJet 816C */   
+	{ 0x03f0, 0x1017, USBLP_QUIRK_GET_ID }, /* HP LaserJet 1300 */
 	{ 0x03f0, 0x1104, USBLP_QUIRK_BIDIR }, /* HP Deskjet 959C */
 	{ 0x0409, 0xefbe, USBLP_QUIRK_BIDIR }, /* NEC Picty900 (HP OEM) */
 	{ 0x0409, 0xbef4, USBLP_QUIRK_BIDIR }, /* NEC Picty760 (HP OEM) */
@@ -201,6 +203,7 @@
 
 static int usblp_select_alts(struct usblp *usblp);
 static int usblp_set_protocol(struct usblp *usblp, int protocol);
+static int usblp_get_device_id_string(struct usblp *usblp);
 static int usblp_cache_device_id_string(struct usblp *usblp);
 
 
@@ -409,7 +412,7 @@
 					goto done;
 				}
 
-				length = usblp_cache_device_id_string(usblp);
+				length = usblp_get_device_id_string(usblp);
 				if (length < 0) {
 					retval = length;
 					goto done;
@@ -469,6 +472,11 @@
 					usblp_set_protocol(usblp,
 						usblp->current_protocol);
 				}
+				/* At this point getting the device ID is safe
+				 * even on buggy printers, because the bulk I/O
+				 * is not in progress (URBs are unlinked). */
+				if (usblp->quirks & USBLP_QUIRK_GET_ID)
+					usblp_cache_device_id_string(usblp);
 				break;
 
 			case IOCNR_HP_SET_CHANNEL:
@@ -962,6 +970,25 @@
 	return 0;
 }
 
+/* Gets the device ID string; either from the device directly (for good
+ * devices) or from the cache (for buggy printers which can lock up if some
+ * bulk I/O is in progress while the device ID is fetched). */
+static int usblp_get_device_id_string(struct usblp *usblp)
+{
+	int length;
+
+	if (!(usblp->quirks & USBLP_QUIRK_GET_ID))
+		return usblp_cache_device_id_string(usblp);
+
+	length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1];
+	if (length < 2)
+		length = 2;
+	else if (length >= DEVICE_ID_SIZE)
+		length = DEVICE_ID_SIZE - 1;
+
+	return length;
+}
+
 /* Retrieves and caches device ID string.
  * Returns length, including length bytes but not null terminator.
  * On error, returns a negative errno value. */
