Toshiba G450 kernel patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I have created patch for linux kernel which handles Toshiba G450
as a HSDPA modem.

For more information please visit
http://www.magdina.org/projects/toshiba-g450-kernel-patch

See attached patch file.

Regards,
Peter Magdina
diff -Nparu linux-2.6.31.1-old/drivers/usb/serial/option.c linux-2.6.31.1-new/drivers/usb/serial/option.c
--- linux-2.6.31.1-old/drivers/usb/serial/option.c	2009-10-03 00:14:54.000000000 +0200
+++ linux-2.6.31.1-new/drivers/usb/serial/option.c	2009-10-03 00:15:54.000000000 +0200
@@ -317,6 +317,7 @@ static int  option_resume(struct usb_ser
 /* TOSHIBA PRODUCTS */
 #define TOSHIBA_VENDOR_ID			0x0930
 #define TOSHIBA_PRODUCT_HSDPA_MINICARD		0x1302
+#define TOSHIBA_PRODUCT_G450			0x0d45
 
 #define ALINK_VENDOR_ID				0x1e0e
 #define ALINK_PRODUCT_3GU			0x9200
@@ -578,6 +579,7 @@ static struct usb_device_id option_ids[]
 	{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
 	{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
 	{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) },
+	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
 	{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
 	{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
diff -Nparu linux-2.6.31.1-old/drivers/usb/storage/Makefile linux-2.6.31.1-new/drivers/usb/storage/Makefile
--- linux-2.6.31.1-old/drivers/usb/storage/Makefile	2009-10-03 00:14:54.000000000 +0200
+++ linux-2.6.31.1-new/drivers/usb/storage/Makefile	2009-10-03 00:15:40.000000000 +0200
@@ -12,7 +12,8 @@ obj-$(CONFIG_USB_STORAGE)	+= usb-storage
 usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG)	+= debug.o
 
 usb-storage-objs :=	scsiglue.o protocol.o transport.o usb.o \
-			initializers.o sierra_ms.o option_ms.o $(usb-storage-obj-y)
+			initializers.o sierra_ms.o option_ms.o \
+		       	toshiba_g450.o $(usb-storage-obj-y)
 
 ifeq ($(CONFIG_USB_LIBUSUAL),)
 	usb-storage-objs	+= usual-tables.o
diff -Nparu linux-2.6.31.1-old/drivers/usb/storage/toshiba_g450.c linux-2.6.31.1-new/drivers/usb/storage/toshiba_g450.c
--- linux-2.6.31.1-old/drivers/usb/storage/toshiba_g450.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.1-new/drivers/usb/storage/toshiba_g450.c	2009-10-03 00:15:40.000000000 +0200
@@ -0,0 +1,162 @@
+/*
+ * Driver for Toshiba G450 HSDPA modem.
+ *
+ *   (c) 2009 Peter Magdina <peter@xxxxxxxxxx>
+ *
+ * Inspired by option_ms.c by Dan Williams <dcbw@xxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/usb.h>
+
+#include "usb.h"
+#include "transport.h"
+#include "toshiba_g450.h"
+#include "debug.h"
+
+#define G450_FORCE_MODEM		0x01
+#define G450_ALLOW_MS 			0x02
+
+static unsigned int toshiba_g450_cd = G450_FORCE_MODEM;
+module_param(toshiba_g450_cd, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(toshiba_g450_cd, "cd mode (1=Force Modem (default),"
+		 " 2=Allow CD-Rom");
+
+#define RESPONSE_LEN 1024
+
+static int toshiba_g450_switchmode(struct us_data *us)
+{
+	const unsigned char switch_msg[] = {
+	  0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78,
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x1b,
+	  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	};
+	char *buffer;
+	int result;
+
+	US_DEBUGP("Toshiba G450: %s", "DEVICE MODE SWITCH\n");
+
+	usb_stor_clear_halt(us, us->send_bulk_pipe);
+
+	buffer = kzalloc(RESPONSE_LEN, GFP_KERNEL);
+	if (buffer == NULL)
+		return USB_STOR_TRANSPORT_ERROR;
+
+	memcpy(buffer, switch_msg, sizeof(switch_msg));
+	result = usb_stor_bulk_transfer_buf(us,
+			us->send_bulk_pipe,
+			buffer, sizeof(switch_msg), NULL);
+	if (result != USB_STOR_XFER_GOOD) {
+		result = USB_STOR_XFER_ERROR;
+		goto out;
+	}
+
+	/* Some of the devices need to be asked for a response, but we don't
+	 * care what that response is.
+	 */
+	usb_stor_bulk_transfer_buf(us,
+			us->recv_bulk_pipe,
+			buffer, RESPONSE_LEN, NULL);
+
+	result = USB_STOR_XFER_GOOD;
+
+	usb_stor_clear_halt(us, us->send_bulk_pipe);
+out:
+	kfree(buffer);
+	return result;
+}
+
+static int toshiba_g450_inquiry(struct us_data *us)
+{
+	const unsigned char inquiry_msg[] = {
+	  0x55, 0x53, 0x42, 0x43, 0x12, 0x34, 0x56, 0x78,
+	  0x24, 0x00, 0x00, 0x00, 0x80, 0x00, 0x06, 0x12,
+	  0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	};
+	char *buffer;
+	int result;
+
+	US_DEBUGP("Toshiba G450: %s", "device inquiry\n");
+
+ 	buffer = kzalloc(0x24, GFP_KERNEL);
+ 	if (buffer == NULL)
+ 		return USB_STOR_TRANSPORT_ERROR;
+
+	memcpy(buffer, inquiry_msg, sizeof(inquiry_msg));
+	result = usb_stor_bulk_transfer_buf(us,
+			us->send_bulk_pipe,
+			buffer, sizeof(inquiry_msg), NULL);
+	if (result != USB_STOR_XFER_GOOD) {
+		result = USB_STOR_XFER_ERROR;
+		goto out;
+	}
+
+	result = usb_stor_bulk_transfer_buf(us,
+			us->recv_bulk_pipe,
+			buffer, 0x24, NULL);
+	if (result != USB_STOR_XFER_GOOD) {
+		result = USB_STOR_XFER_ERROR;
+		goto out;
+	}
+
+	/* Read the CSW */
+	usb_stor_bulk_transfer_buf(us,
+			us->recv_bulk_pipe,
+			buffer, 13, NULL);
+
+out:
+	kfree(buffer);
+	return result;
+}
+
+
+int toshiba_g450_init(struct us_data *us)
+{
+	int result;
+
+	US_DEBUGP("Toshiba G450: toshiba_g450_init called\n");
+
+	/* Additional test for vendor information via INQUIRY,
+	 * because some vendor/product IDs are ambiguous
+	 */
+	result = toshiba_g450_inquiry(us);
+	if (result != 0) {
+		US_DEBUGP("Toshiba G450: vendor is not Toshiba or not determinable,"
+			  " no action taken\n");
+		return 0;
+	} else
+		US_DEBUGP("Toshiba G450: this is a genuine Toshiba device,"
+			  " proceeding\n");
+
+	/* Force Modem mode */
+	if (toshiba_g450_cd == G450_FORCE_MODEM) {
+		US_DEBUGP("Toshiba G450: %s", "Forcing Modem Mode\n");
+		result = toshiba_g450_switchmode(us);
+		if (result != USB_STOR_XFER_GOOD) {
+			US_DEBUGP("Toshiba G450: Failed to switch to modem mode.\n");
+            		return -EIO;
+        	}
+	} else if (toshiba_g450_cd == G450_ALLOW_MS) {
+		/* Allow Mass Storage mode (keep CD-Rom) */
+		US_DEBUGP("Toshiba G450: %s", "Allowing Mass Storage Mode if device"
+		          " requests it\n");
+	}
+
+	return 0;
+}
+
diff -Nparu linux-2.6.31.1-old/drivers/usb/storage/toshiba_g450.h linux-2.6.31.1-new/drivers/usb/storage/toshiba_g450.h
--- linux-2.6.31.1-old/drivers/usb/storage/toshiba_g450.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.31.1-new/drivers/usb/storage/toshiba_g450.h	2009-10-03 00:15:40.000000000 +0200
@@ -0,0 +1,4 @@
+#ifndef _TOSHIBA_G450_H_
+#define _TOSHIBA_G450_H_
+extern int toshiba_g450_init(struct us_data *us);
+#endif
diff -Nparu linux-2.6.31.1-old/drivers/usb/storage/unusual_devs.h linux-2.6.31.1-new/drivers/usb/storage/unusual_devs.h
--- linux-2.6.31.1-old/drivers/usb/storage/unusual_devs.h	2009-10-03 00:14:54.000000000 +0200
+++ linux-2.6.31.1-new/drivers/usb/storage/unusual_devs.h	2009-10-03 00:15:41.000000000 +0200
@@ -1110,6 +1110,13 @@ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xf
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
+/* Patch by Peter Magdina <peter@xxxxxxxxxx> */
+UNUSUAL_DEV(  0x0930, 0x0d46, 0x0000, 0x0000,
+		"Toshiba G450",
+		"Mass Storage",
+		US_SC_DEVICE, US_PR_DEVICE, toshiba_g450_init,
+		0),
+
 /* This Pentax still camera is not conformant
  * to the USB storage specification: -
  * - It does not like the INQUIRY command. So we must handle this command
diff -Nparu linux-2.6.31.1-old/drivers/usb/storage/usb.c linux-2.6.31.1-new/drivers/usb/storage/usb.c
--- linux-2.6.31.1-old/drivers/usb/storage/usb.c	2009-10-03 00:14:54.000000000 +0200
+++ linux-2.6.31.1-new/drivers/usb/storage/usb.c	2009-10-03 00:15:42.000000000 +0200
@@ -68,6 +68,7 @@
 
 #include "sierra_ms.h"
 #include "option_ms.h"
+#include "toshiba_g450.h"
 
 /* Some informational data */
 MODULE_AUTHOR("Matthew Dharm <mdharm-usb@xxxxxxxxxxxxxxxxxx>");

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux