Sunday, January 23, 2011

Qualcomm USB Drivers for Windows 7 x64

All drivers on Windows 7 need to be signed. For some reason unknown to man, Qualcomm doesn't have a signed driver for their products, they leave it up to the OEM's.

Fortunately, the INF file of existing drivers for Gobi can be tweaked to make it work with other QC devices.  Here's the results of last weekend's anomolous (and anonymous) hacking...

First, the QC device enumerates as 3 devices, shown below.  With no driver installed, it just says Qualcomm MSM.



So, we'll need to add a driver for each interface of the composite QC device.  Next question is: what drivers?   We can do a little more searching and find some unpublished documents, or better, use a good source like the Linux kernel.

http://lxr.linux.no/#linux+v2.6.37/drivers/usb/serial/qcserial.c

Looking here, we can see it's actually enumerated as 2 serial ports and 1 modem port.  Alright, now we have all the information we need.  Now it's time to plan our hack...  Here's what we're gonna do.
  1. Find some signed Gobi drivers from any laptop OEM, such as Lenovo, that ships serial and modem drivers
  2. Modify the inf's for the modem device and the usb serial device .inf files to add the vid/pids we are interested in for our devices
  3. Point device manager to these drivers

Ok, on to the work...  I spent some time searching for gobi drivers, and the ones I found first were from Lenovo.  First come, first served, so let's use those.  Download the drivers from Lenovo:


http://www-307.ibm.com/pc/support/site.wss/MIGR-69999.html

Run the extractor, and it will extract them to c:\drivers.   Navigate to this folder

C:\DRIVERS\WIN\WWANQL\Driver\Source\Module Retargetable Folder\QCUSB-Lenovo\DriverPackage\Qualcomm\Win64\AMD64

This is the driver package portion we are interested it.


Looking at the inf files, the ones we are interested in are the usbser (usb serial) and mdm (modem). The net driver (qcnetlno.inf) is the driver that is used for to make the modem show up as a network interface (ala RNDIS), not applicable here...

First let's modify the mdm file to get the modem enumerated.  Look in device manager and edit the properties of one of the USB devices.   Right-click the device, driver, properties, and you'll see this:



So you can see that our PID is 9002.  Depending on the chipset, etc, the PID may be different.  You can check the linux source for examples of other common PID's.  The _00 is the interface number, in the this case 0, or the first interface (USB interface #'s are zero-based indexed).  Other interfaces will be _01, 02, etc..  Now we need to figure out which interface to associate with which driver, and then associate the driver with the VID/PID (vendor ID and product ID) of the modem we are interested in.

Being smart, let's look at what was done with the Gobi driver.  Looking in the modem and ser .inf files, we can see that interface _00 and _01 are the serial interfaces for diag and NMEA, and interface _02 is the modem interface.   So, we need to add the modem interface to the qcmdmlno.inf file, and the serial interfaces for diag and NMEA to qcusbserlno.inf.  IMPORTANT NOTE:  these interfaces numbers can be different, this just happens to work for the chipset used in my device!

Now we modify the .INF's.   Let's do the MDM interface first.   Edit qcmdmlno.inf (with VIM, of course!).  Everywhere we find the PID used, we need to add another entry for our PID.  For example, in my .INF file, because my PID is 9002, I added the following entries (see my diff below...   for those not familiar with diffs, + is an added line)


***************
*** 24,39 ****
--- 24,42 ----
  [ControlFlags]
  ExcludeFromSelect = *

  [Models]
  %QUALCOMM92022% = Modem2, USB\VID_05C6&PID_9202&MI_02
+ %QUALCOMM90022% = Modem2, USB\VID_05C6&PID_9002&MI_02

  [Models.NTamd64]
  %QUALCOMM92022% = Modem2, USB\VID_05C6&PID_9202&MI_02
+ %QUALCOMM90022% = Modem2, USB\VID_05C6&PID_9002&MI_02

  [Models.NTia64]
  %QUALCOMM92022% = Modem2, USB\VID_05C6&PID_9202&MI_02
+ %QUALCOMM90022% = Modem2, USB\VID_05C6&PID_9002&MI_02

  [Modem2.NT]
  CopyFiles=QCUsbDriverFiles
  AddReg = All, MfgAddReg, Modem1.AddReg, USB

***************
*** 62,71 ****
--- 65,75 ----
  [Strings]
  QCUSBSER = "Lenovo USB Device for Legacy Serial Communication"
  QcomSrcDisk = "Lenovo USB Driver Disk"
  QUALCOMM   = "Qualcomm Incorporated"
  QUALCOMM92022 = "Qualcomm HS-USB Modem 9202"
+ QUALCOMM90022 = "Qualcomm HS-USB Modem 9002"

  [All]
  HKR,,FriendlyDriver,0,Unimodem.vxd
  HKR,,DevLoader,0,*vcomm
  HKR,,ConfigDialog,0,modemui.dll


 So, add the above entries to the qcmdmLno.inf.  Done.   The driver should now load correctly for the modem interface.

Now let's move on to the USB serial ports for Diag and NMEA.   Using the same approach, we will add the _00 and _01 ports the qcserlno.inf file.  Below is what I did:

***************
*** 25,44 ****
--- 25,50 ----

  [QcomSerialPortlno]
  %QcomDevice92010%  = QportInstall00, USB\VID_05C6&PID_9201
  %QcomDevice92020%  = QportInstall00, USB\VID_05C6&PID_9202&MI_00
  %QcomDevice92021%  = QportInstall00, USB\VID_05C6&PID_9202&MI_01
+ %QcomDevice90020%  = QportInstall00, USB\VID_05C6&PID_9002&MI_00
+ %QcomDevice90021%  = QportInstall00, USB\VID_05C6&PID_9002&MI_01

  [QcomSerialPortlno.NTia64]
  %QcomDevice92010%  = QportInstall00, USB\VID_05C6&PID_9201
  %QcomDevice92020%  = QportInstall00, USB\VID_05C6&PID_9202&MI_00
  %QcomDevice92021%  = QportInstall00, USB\VID_05C6&PID_9202&MI_01
+ %QcomDevice90020%  = QportInstall00, USB\VID_05C6&PID_9002&MI_00
+ %QcomDevice90021%  = QportInstall00, USB\VID_05C6&PID_9002&MI_01

  [QcomSerialPortlno.NTamd64]
  %QcomDevice92010%  = QportInstall00, USB\VID_05C6&PID_9201
  %QcomDevice92020%  = QportInstall00, USB\VID_05C6&PID_9202&MI_00
  %QcomDevice92021%  = QportInstall00, USB\VID_05C6&PID_9202&MI_01
+ %QcomDevice90020%  = QportInstall00, USB\VID_05C6&PID_9002&MI_00
+ %QcomDevice90021%  = QportInstall00, USB\VID_05C6&PID_9002&MI_01

  [QportInstall00.NT]
  CopyFiles=QCUsbDriverFiles
  AddReg = All00, AddReg

***************
*** 70,75 ****
--- 76,83 ----
  QcomSrcDisk = "Lenovo USB Driver Disk"
  QUALCOMM   = "Qualcomm Incorporated"
  QcomDevice92010 = "Qualcomm HS-USB QDLoader 9201"
  QcomDevice92020 = "Qualcomm HS-USB Diagnostics 9202"
  QcomDevice92021 = "Qualcomm HS-USB NMEA 9202"
+ QcomDevice90020 = "Qualcomm HS-USB Diagnostics 9002"
+ QcomDevice90021 = "Qualcomm HS-USB NMEA 9002"


Again, this is for the PID's for my device.  Your device may have a different PID.  Add these to qcserlno.inf (or whichever driver set you hijacked).

Ok, now let's test this.   Go through each interface in the Device Manager and update the driver.  To do that:


  1. start device manager
  2. find the Qualcomm devices listed in the "other devices" box as shown in the screenshot earlier
  3. right-click on each device, and select "Update Driver Software"
  4. the next dialog box will be "Update driver Software", select "Browse my computer for driver software"
  5. Navigate to where you saved the drivers in "update drivers" dialog 


  6. Select "Install this driver anway" when you are prompted about verifying the publisher of the driver
  7. Repeat for each device in the list (3 times, in my case)
Ok, after doing this, you should see all the devices loaded, as shown below

Now let's test it!   Right-click on the modem, and select properties, and select the "Diagnostics" tab.   Press the Query Modem button, wait a few seconds, and you should see a response come back that says "success".   It works!


Here's a link to the drivers + modified INF, zipped up, that some friends were kind enough to host.

http://www.bluelibris.com/files/signed_usb_drivers.zip


    1 comment:

    1. Your tutorial is tooo hard to follow.

      But u are so nice , u have uploaded modified drives.

      It really worked.

      I appriciate it.

      Thanks

      ReplyDelete